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,67 +1,67 @@
|
|
|
1
|
-
# Template: Provider — $1
|
|
2
|
-
|
|
3
|
-
## Files to Create
|
|
4
|
-
|
|
5
|
-
1. `src/providers/$1.ts` — provider implementation (extends BaseProvider)
|
|
6
|
-
2. Update `src/constants.ts` — add to PROVIDER_REGISTRY
|
|
7
|
-
3. `src/__tests__/providers/$1.test.ts` — test with mocked API calls
|
|
8
|
-
|
|
9
|
-
## Provider Implementation
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
// src/providers/$1.ts
|
|
13
|
-
import {
|
|
14
|
-
BaseProvider,
|
|
15
|
-
type ProviderServer,
|
|
16
|
-
type CreateServerParams,
|
|
17
|
-
type ProviderResponse,
|
|
18
|
-
} from './base.js';
|
|
19
|
-
|
|
20
|
-
export class $1Provider extends BaseProvider {
|
|
21
|
-
constructor(token: string) {
|
|
22
|
-
super(token, 'https://api.$1.com/v1'); // adjust API base URL
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async listServers(): Promise<ProviderResponse<ProviderServer[]>> {
|
|
26
|
-
return this.request<ProviderServer[]>('GET', '/servers');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async createServer(params: CreateServerParams): Promise<ProviderResponse<ProviderServer>> {
|
|
30
|
-
return this.request<ProviderServer>('POST', '/servers', { body: params });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async deleteServer(serverId: string): Promise<ProviderResponse<void>> {
|
|
34
|
-
return this.request<void>('DELETE', `/servers/${serverId}`);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async getServer(serverId: string): Promise<ProviderResponse<ProviderServer>> {
|
|
38
|
-
return this.request<ProviderServer>('GET', `/servers/${serverId}`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## PROVIDER_REGISTRY Entry
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
// In src/constants.ts — add to PROVIDER_REGISTRY (single source of truth)
|
|
47
|
-
import { $1Provider } from './providers/$1.js';
|
|
48
|
-
|
|
49
|
-
export const PROVIDER_REGISTRY = {
|
|
50
|
-
// ... existing providers
|
|
51
|
-
$1: {
|
|
52
|
-
name: '$1',
|
|
53
|
-
envKey: '$1_TOKEN', // e.g., 'OVHCLOUD_TOKEN'
|
|
54
|
-
class: $1Provider,
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Next Steps
|
|
60
|
-
|
|
61
|
-
- [ ] Register in `PROVIDER_REGISTRY` (src/constants.ts) — single source of truth
|
|
62
|
-
- [ ] Implement `stripSensitiveData()` to remove API tokens from error responses
|
|
63
|
-
- [ ] Use `assertValidIp()` before any SSH operation
|
|
64
|
-
- [ ] Use `withProviderErrorHandling()` HOF for API error consistency
|
|
65
|
-
- [ ] Write tests with mocked axios (mock `axios.create()` → `jest.fn(() => axios)`)
|
|
66
|
-
- [ ] Add "Getting Your API Token" section to README.md
|
|
67
|
-
- [ ] Run `npm run build && npm test && npm run lint`
|
|
1
|
+
# Template: Provider — $1
|
|
2
|
+
|
|
3
|
+
## Files to Create
|
|
4
|
+
|
|
5
|
+
1. `src/providers/$1.ts` — provider implementation (extends BaseProvider)
|
|
6
|
+
2. Update `src/constants.ts` — add to PROVIDER_REGISTRY
|
|
7
|
+
3. `src/__tests__/providers/$1.test.ts` — test with mocked API calls
|
|
8
|
+
|
|
9
|
+
## Provider Implementation
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// src/providers/$1.ts
|
|
13
|
+
import {
|
|
14
|
+
BaseProvider,
|
|
15
|
+
type ProviderServer,
|
|
16
|
+
type CreateServerParams,
|
|
17
|
+
type ProviderResponse,
|
|
18
|
+
} from './base.js';
|
|
19
|
+
|
|
20
|
+
export class $1Provider extends BaseProvider {
|
|
21
|
+
constructor(token: string) {
|
|
22
|
+
super(token, 'https://api.$1.com/v1'); // adjust API base URL
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async listServers(): Promise<ProviderResponse<ProviderServer[]>> {
|
|
26
|
+
return this.request<ProviderServer[]>('GET', '/servers');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async createServer(params: CreateServerParams): Promise<ProviderResponse<ProviderServer>> {
|
|
30
|
+
return this.request<ProviderServer>('POST', '/servers', { body: params });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async deleteServer(serverId: string): Promise<ProviderResponse<void>> {
|
|
34
|
+
return this.request<void>('DELETE', `/servers/${serverId}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async getServer(serverId: string): Promise<ProviderResponse<ProviderServer>> {
|
|
38
|
+
return this.request<ProviderServer>('GET', `/servers/${serverId}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## PROVIDER_REGISTRY Entry
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// In src/constants.ts — add to PROVIDER_REGISTRY (single source of truth)
|
|
47
|
+
import { $1Provider } from './providers/$1.js';
|
|
48
|
+
|
|
49
|
+
export const PROVIDER_REGISTRY = {
|
|
50
|
+
// ... existing providers
|
|
51
|
+
$1: {
|
|
52
|
+
name: '$1',
|
|
53
|
+
envKey: '$1_TOKEN', // e.g., 'OVHCLOUD_TOKEN'
|
|
54
|
+
class: $1Provider,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Next Steps
|
|
60
|
+
|
|
61
|
+
- [ ] Register in `PROVIDER_REGISTRY` (src/constants.ts) — single source of truth
|
|
62
|
+
- [ ] Implement `stripSensitiveData()` to remove API tokens from error responses
|
|
63
|
+
- [ ] Use `assertValidIp()` before any SSH operation
|
|
64
|
+
- [ ] Use `withProviderErrorHandling()` HOF for API error consistency
|
|
65
|
+
- [ ] Write tests with mocked axios (mock `axios.create()` → `jest.fn(() => axios)`)
|
|
66
|
+
- [ ] Add "Getting Your API Token" section to README.md
|
|
67
|
+
- [ ] Run `npm run build && npm test && npm run lint`
|
|
@@ -1,180 +1,180 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# scaffold.sh — Generate Kastell component boilerplate from templates.
|
|
3
|
-
# Usage: scaffold.sh <type> <name> [--dry-run]
|
|
4
|
-
# type: command | check | provider | mcp-tool
|
|
5
|
-
# name: kebab-case component name (e.g., server-migrate, filesystem-perms)
|
|
6
|
-
#
|
|
7
|
-
# Ersin criterion: This script runs without an LLM. Deterministic file generation.
|
|
8
|
-
|
|
9
|
-
set -euo pipefail
|
|
10
|
-
|
|
11
|
-
# ── Resolve script directory (works in symlink/Git Bash/etc) ──
|
|
12
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
-
TEMPLATE_DIR="$SCRIPT_DIR/../templates"
|
|
14
|
-
PROJECT_ROOT="${PROJECT_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
|
|
15
|
-
|
|
16
|
-
# ── Colors ──
|
|
17
|
-
RED='\033[0;31m'
|
|
18
|
-
GREEN='\033[0;32m'
|
|
19
|
-
YELLOW='\033[1;33m'
|
|
20
|
-
CYAN='\033[0;36m'
|
|
21
|
-
NC='\033[0m' # No Color
|
|
22
|
-
|
|
23
|
-
info() { echo -e "${CYAN}ℹ${NC} $*"; }
|
|
24
|
-
ok() { echo -e "${GREEN}✓${NC} $*"; }
|
|
25
|
-
warn() { echo -e "${YELLOW}⚠${NC} $*"; }
|
|
26
|
-
err() { echo -e "${RED}✗${NC} $*" >&2; }
|
|
27
|
-
|
|
28
|
-
# ── Args ──
|
|
29
|
-
TYPE="${1:-}"
|
|
30
|
-
NAME="${2:-}"
|
|
31
|
-
DRY_RUN=false
|
|
32
|
-
for arg in "$@"; do [[ "$arg" == "--dry-run" ]] && DRY_RUN=true; done
|
|
33
|
-
|
|
34
|
-
if [[ -z "$TYPE" || -z "$NAME" ]]; then
|
|
35
|
-
echo "Usage: scaffold.sh <type> <name> [--dry-run]"
|
|
36
|
-
echo " type: command | check | provider | mcp-tool"
|
|
37
|
-
echo " name: kebab-case (e.g., server-migrate)"
|
|
38
|
-
exit 1
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
|
-
# Validate type
|
|
42
|
-
case "$TYPE" in
|
|
43
|
-
command|check|provider|mcp-tool) ;;
|
|
44
|
-
*) err "Unknown type: $TYPE (valid: command, check, provider, mcp-tool)"; exit 1 ;;
|
|
45
|
-
esac
|
|
46
|
-
|
|
47
|
-
# Validate name (kebab-case or snake_case, lowercase)
|
|
48
|
-
if [[ ! "$NAME" =~ ^[a-z][a-z0-9_-]*$ ]]; then
|
|
49
|
-
err "Invalid name: $NAME (must be lowercase kebab-case or snake_case)"
|
|
50
|
-
exit 1
|
|
51
|
-
fi
|
|
52
|
-
|
|
53
|
-
# ── Name transformations ──
|
|
54
|
-
to_pascal() {
|
|
55
|
-
echo "$1" | sed 's/[-_]/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1' | tr -d ' '
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
to_camel() {
|
|
59
|
-
local pascal
|
|
60
|
-
pascal=$(to_pascal "$1")
|
|
61
|
-
echo "$(echo "${pascal:0:1}" | tr 'A-Z' 'a-z')${pascal:1}"
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
to_upper() {
|
|
65
|
-
echo "$1" | tr '[:lower:]' '[:upper:]' | tr '-' '_'
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
NAME_PASCAL=$(to_pascal "$NAME")
|
|
69
|
-
NAME_CAMEL=$(to_camel "$NAME")
|
|
70
|
-
NAME_UPPER=$(to_upper "$NAME")
|
|
71
|
-
|
|
72
|
-
info "Scaffolding $TYPE: $NAME"
|
|
73
|
-
info " PascalCase: $NAME_PASCAL"
|
|
74
|
-
info " camelCase: $NAME_CAMEL"
|
|
75
|
-
info " UPPER: $NAME_UPPER"
|
|
76
|
-
echo ""
|
|
77
|
-
|
|
78
|
-
# ── Template processing ──
|
|
79
|
-
process_template() {
|
|
80
|
-
local tpl_file="$1"
|
|
81
|
-
local output_file="$2"
|
|
82
|
-
|
|
83
|
-
if [[ ! -f "$tpl_file" ]]; then
|
|
84
|
-
err "Template not found: $tpl_file"
|
|
85
|
-
return 1
|
|
86
|
-
fi
|
|
87
|
-
|
|
88
|
-
if [[ -f "$output_file" ]] && [[ "$DRY_RUN" == false ]]; then
|
|
89
|
-
err "File already exists: $output_file (won't overwrite)"
|
|
90
|
-
return 1
|
|
91
|
-
fi
|
|
92
|
-
|
|
93
|
-
local content
|
|
94
|
-
content=$(sed \
|
|
95
|
-
-e "s/__NAME__/$NAME/g" \
|
|
96
|
-
-e "s/__NAME_PASCAL__/$NAME_PASCAL/g" \
|
|
97
|
-
-e "s/__NAME_CAMEL__/$NAME_CAMEL/g" \
|
|
98
|
-
-e "s/__NAME_UPPER__/$NAME_UPPER/g" \
|
|
99
|
-
"$tpl_file")
|
|
100
|
-
|
|
101
|
-
if [[ "$DRY_RUN" == true ]]; then
|
|
102
|
-
warn "[dry-run] Would create: $output_file"
|
|
103
|
-
echo "$content"
|
|
104
|
-
echo "---"
|
|
105
|
-
else
|
|
106
|
-
mkdir -p "$(dirname "$output_file")"
|
|
107
|
-
echo "$content" > "$output_file"
|
|
108
|
-
ok "Created: $output_file"
|
|
109
|
-
fi
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
# ── File mapping per type ──
|
|
113
|
-
CREATED=0
|
|
114
|
-
|
|
115
|
-
case "$TYPE" in
|
|
116
|
-
command)
|
|
117
|
-
process_template "$TEMPLATE_DIR/command.ts.tpl" "$PROJECT_ROOT/src/commands/$NAME.ts" && ((CREATED++)) || true
|
|
118
|
-
process_template "$TEMPLATE_DIR/command-core.ts.tpl" "$PROJECT_ROOT/src/core/$NAME.ts" && ((CREATED++)) || true
|
|
119
|
-
process_template "$TEMPLATE_DIR/command-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/core/$NAME.test.ts" && ((CREATED++)) || true
|
|
120
|
-
|
|
121
|
-
echo ""
|
|
122
|
-
warn "Next steps:"
|
|
123
|
-
echo " 1. Register command in src/index.ts"
|
|
124
|
-
echo " 2. Implement core logic in src/core/$NAME.ts"
|
|
125
|
-
echo " 3. Add isSafeMode() check if destructive"
|
|
126
|
-
echo " 4. Run: npm run build && npm test && npm run lint"
|
|
127
|
-
echo " 5. Update README.md command table"
|
|
128
|
-
;;
|
|
129
|
-
|
|
130
|
-
check)
|
|
131
|
-
process_template "$TEMPLATE_DIR/check.ts.tpl" "$PROJECT_ROOT/src/core/audit/checks/$NAME.ts" && ((CREATED++)) || true
|
|
132
|
-
process_template "$TEMPLATE_DIR/check-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/core/audit/checks/$NAME.test.ts" && ((CREATED++)) || true
|
|
133
|
-
|
|
134
|
-
echo ""
|
|
135
|
-
warn "Next steps:"
|
|
136
|
-
echo " 1. Add SSH section in src/core/audit/commands.ts:"
|
|
137
|
-
echo " NAMED_SEP(\"${NAME_UPPER}\") + bash commands"
|
|
138
|
-
echo " 2. Register in src/core/audit/checks/index.ts:"
|
|
139
|
-
echo " { name: \"$NAME_PASCAL\", sectionName: \"$NAME_UPPER\", parser: parse${NAME_PASCAL}Checks }"
|
|
140
|
-
echo " 3. Add compliance mapping in src/core/audit/compliance/mapper.ts (optional)"
|
|
141
|
-
echo " 4. Run: npm run build && npm test && npm run lint"
|
|
142
|
-
echo " 5. Test: kastell audit --list-checks | grep $NAME_UPPER"
|
|
143
|
-
;;
|
|
144
|
-
|
|
145
|
-
provider)
|
|
146
|
-
process_template "$TEMPLATE_DIR/provider.ts.tpl" "$PROJECT_ROOT/src/providers/$NAME.ts" && ((CREATED++)) || true
|
|
147
|
-
process_template "$TEMPLATE_DIR/provider-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/providers/$NAME.test.ts" && ((CREATED++)) || true
|
|
148
|
-
|
|
149
|
-
echo ""
|
|
150
|
-
warn "Next steps:"
|
|
151
|
-
echo " 1. Add to PROVIDER_REGISTRY in src/constants.ts:"
|
|
152
|
-
echo " $NAME: { name: \"$NAME_PASCAL\", envKey: \"${NAME_UPPER}_TOKEN\", class: ${NAME_PASCAL}Provider }"
|
|
153
|
-
echo " 2. Implement API methods (adjust base URL)"
|
|
154
|
-
echo " 3. Add stripSensitiveData() token cleanup"
|
|
155
|
-
echo " 4. Run: npm run build && npm test && npm run lint"
|
|
156
|
-
echo " 5. Add 'Getting Your API Token' to README.md"
|
|
157
|
-
;;
|
|
158
|
-
|
|
159
|
-
mcp-tool)
|
|
160
|
-
process_template "$TEMPLATE_DIR/mcp-tool.ts.tpl" "$PROJECT_ROOT/src/mcp/tools/$NAME.ts" && ((CREATED++)) || true
|
|
161
|
-
process_template "$TEMPLATE_DIR/mcp-tool-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/mcp/$NAME.test.ts" && ((CREATED++)) || true
|
|
162
|
-
|
|
163
|
-
echo ""
|
|
164
|
-
warn "Next steps:"
|
|
165
|
-
echo " 1. Register in src/mcp/server.ts:"
|
|
166
|
-
echo " registerTool('$NAME', { schema: ${NAME_CAMEL}Schema, handler: handle${NAME_PASCAL} })"
|
|
167
|
-
echo " 2. Define Zod schema (flat object, NOT z.object() wrapper)"
|
|
168
|
-
echo " 3. Handler delegates to core/ (NOT direct SSH/provider)"
|
|
169
|
-
echo " 4. Add SAFE_MODE check if destructive"
|
|
170
|
-
echo " 5. Run: npm run build && npm test && npm run lint"
|
|
171
|
-
echo " 6. Update README.md MCP tools table"
|
|
172
|
-
;;
|
|
173
|
-
esac
|
|
174
|
-
|
|
175
|
-
echo ""
|
|
176
|
-
if [[ "$DRY_RUN" == true ]]; then
|
|
177
|
-
info "[dry-run] No files were created."
|
|
178
|
-
else
|
|
179
|
-
ok "Scaffolded $CREATED file(s) for $TYPE: $NAME"
|
|
180
|
-
fi
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scaffold.sh — Generate Kastell component boilerplate from templates.
|
|
3
|
+
# Usage: scaffold.sh <type> <name> [--dry-run]
|
|
4
|
+
# type: command | check | provider | mcp-tool
|
|
5
|
+
# name: kebab-case component name (e.g., server-migrate, filesystem-perms)
|
|
6
|
+
#
|
|
7
|
+
# Ersin criterion: This script runs without an LLM. Deterministic file generation.
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
# ── Resolve script directory (works in symlink/Git Bash/etc) ──
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
TEMPLATE_DIR="$SCRIPT_DIR/../templates"
|
|
14
|
+
PROJECT_ROOT="${PROJECT_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
|
|
15
|
+
|
|
16
|
+
# ── Colors ──
|
|
17
|
+
RED='\033[0;31m'
|
|
18
|
+
GREEN='\033[0;32m'
|
|
19
|
+
YELLOW='\033[1;33m'
|
|
20
|
+
CYAN='\033[0;36m'
|
|
21
|
+
NC='\033[0m' # No Color
|
|
22
|
+
|
|
23
|
+
info() { echo -e "${CYAN}ℹ${NC} $*"; }
|
|
24
|
+
ok() { echo -e "${GREEN}✓${NC} $*"; }
|
|
25
|
+
warn() { echo -e "${YELLOW}⚠${NC} $*"; }
|
|
26
|
+
err() { echo -e "${RED}✗${NC} $*" >&2; }
|
|
27
|
+
|
|
28
|
+
# ── Args ──
|
|
29
|
+
TYPE="${1:-}"
|
|
30
|
+
NAME="${2:-}"
|
|
31
|
+
DRY_RUN=false
|
|
32
|
+
for arg in "$@"; do [[ "$arg" == "--dry-run" ]] && DRY_RUN=true; done
|
|
33
|
+
|
|
34
|
+
if [[ -z "$TYPE" || -z "$NAME" ]]; then
|
|
35
|
+
echo "Usage: scaffold.sh <type> <name> [--dry-run]"
|
|
36
|
+
echo " type: command | check | provider | mcp-tool"
|
|
37
|
+
echo " name: kebab-case (e.g., server-migrate)"
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Validate type
|
|
42
|
+
case "$TYPE" in
|
|
43
|
+
command|check|provider|mcp-tool) ;;
|
|
44
|
+
*) err "Unknown type: $TYPE (valid: command, check, provider, mcp-tool)"; exit 1 ;;
|
|
45
|
+
esac
|
|
46
|
+
|
|
47
|
+
# Validate name (kebab-case or snake_case, lowercase)
|
|
48
|
+
if [[ ! "$NAME" =~ ^[a-z][a-z0-9_-]*$ ]]; then
|
|
49
|
+
err "Invalid name: $NAME (must be lowercase kebab-case or snake_case)"
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# ── Name transformations ──
|
|
54
|
+
to_pascal() {
|
|
55
|
+
echo "$1" | sed 's/[-_]/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1' | tr -d ' '
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
to_camel() {
|
|
59
|
+
local pascal
|
|
60
|
+
pascal=$(to_pascal "$1")
|
|
61
|
+
echo "$(echo "${pascal:0:1}" | tr 'A-Z' 'a-z')${pascal:1}"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
to_upper() {
|
|
65
|
+
echo "$1" | tr '[:lower:]' '[:upper:]' | tr '-' '_'
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
NAME_PASCAL=$(to_pascal "$NAME")
|
|
69
|
+
NAME_CAMEL=$(to_camel "$NAME")
|
|
70
|
+
NAME_UPPER=$(to_upper "$NAME")
|
|
71
|
+
|
|
72
|
+
info "Scaffolding $TYPE: $NAME"
|
|
73
|
+
info " PascalCase: $NAME_PASCAL"
|
|
74
|
+
info " camelCase: $NAME_CAMEL"
|
|
75
|
+
info " UPPER: $NAME_UPPER"
|
|
76
|
+
echo ""
|
|
77
|
+
|
|
78
|
+
# ── Template processing ──
|
|
79
|
+
process_template() {
|
|
80
|
+
local tpl_file="$1"
|
|
81
|
+
local output_file="$2"
|
|
82
|
+
|
|
83
|
+
if [[ ! -f "$tpl_file" ]]; then
|
|
84
|
+
err "Template not found: $tpl_file"
|
|
85
|
+
return 1
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
if [[ -f "$output_file" ]] && [[ "$DRY_RUN" == false ]]; then
|
|
89
|
+
err "File already exists: $output_file (won't overwrite)"
|
|
90
|
+
return 1
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
local content
|
|
94
|
+
content=$(sed \
|
|
95
|
+
-e "s/__NAME__/$NAME/g" \
|
|
96
|
+
-e "s/__NAME_PASCAL__/$NAME_PASCAL/g" \
|
|
97
|
+
-e "s/__NAME_CAMEL__/$NAME_CAMEL/g" \
|
|
98
|
+
-e "s/__NAME_UPPER__/$NAME_UPPER/g" \
|
|
99
|
+
"$tpl_file")
|
|
100
|
+
|
|
101
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
102
|
+
warn "[dry-run] Would create: $output_file"
|
|
103
|
+
echo "$content"
|
|
104
|
+
echo "---"
|
|
105
|
+
else
|
|
106
|
+
mkdir -p "$(dirname "$output_file")"
|
|
107
|
+
echo "$content" > "$output_file"
|
|
108
|
+
ok "Created: $output_file"
|
|
109
|
+
fi
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# ── File mapping per type ──
|
|
113
|
+
CREATED=0
|
|
114
|
+
|
|
115
|
+
case "$TYPE" in
|
|
116
|
+
command)
|
|
117
|
+
process_template "$TEMPLATE_DIR/command.ts.tpl" "$PROJECT_ROOT/src/commands/$NAME.ts" && ((CREATED++)) || true
|
|
118
|
+
process_template "$TEMPLATE_DIR/command-core.ts.tpl" "$PROJECT_ROOT/src/core/$NAME.ts" && ((CREATED++)) || true
|
|
119
|
+
process_template "$TEMPLATE_DIR/command-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/core/$NAME.test.ts" && ((CREATED++)) || true
|
|
120
|
+
|
|
121
|
+
echo ""
|
|
122
|
+
warn "Next steps:"
|
|
123
|
+
echo " 1. Register command in src/index.ts"
|
|
124
|
+
echo " 2. Implement core logic in src/core/$NAME.ts"
|
|
125
|
+
echo " 3. Add isSafeMode() check if destructive"
|
|
126
|
+
echo " 4. Run: npm run build && npm test && npm run lint"
|
|
127
|
+
echo " 5. Update README.md command table"
|
|
128
|
+
;;
|
|
129
|
+
|
|
130
|
+
check)
|
|
131
|
+
process_template "$TEMPLATE_DIR/check.ts.tpl" "$PROJECT_ROOT/src/core/audit/checks/$NAME.ts" && ((CREATED++)) || true
|
|
132
|
+
process_template "$TEMPLATE_DIR/check-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/core/audit/checks/$NAME.test.ts" && ((CREATED++)) || true
|
|
133
|
+
|
|
134
|
+
echo ""
|
|
135
|
+
warn "Next steps:"
|
|
136
|
+
echo " 1. Add SSH section in src/core/audit/commands.ts:"
|
|
137
|
+
echo " NAMED_SEP(\"${NAME_UPPER}\") + bash commands"
|
|
138
|
+
echo " 2. Register in src/core/audit/checks/index.ts:"
|
|
139
|
+
echo " { name: \"$NAME_PASCAL\", sectionName: \"$NAME_UPPER\", parser: parse${NAME_PASCAL}Checks }"
|
|
140
|
+
echo " 3. Add compliance mapping in src/core/audit/compliance/mapper.ts (optional)"
|
|
141
|
+
echo " 4. Run: npm run build && npm test && npm run lint"
|
|
142
|
+
echo " 5. Test: kastell audit --list-checks | grep $NAME_UPPER"
|
|
143
|
+
;;
|
|
144
|
+
|
|
145
|
+
provider)
|
|
146
|
+
process_template "$TEMPLATE_DIR/provider.ts.tpl" "$PROJECT_ROOT/src/providers/$NAME.ts" && ((CREATED++)) || true
|
|
147
|
+
process_template "$TEMPLATE_DIR/provider-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/providers/$NAME.test.ts" && ((CREATED++)) || true
|
|
148
|
+
|
|
149
|
+
echo ""
|
|
150
|
+
warn "Next steps:"
|
|
151
|
+
echo " 1. Add to PROVIDER_REGISTRY in src/constants.ts:"
|
|
152
|
+
echo " $NAME: { name: \"$NAME_PASCAL\", envKey: \"${NAME_UPPER}_TOKEN\", class: ${NAME_PASCAL}Provider }"
|
|
153
|
+
echo " 2. Implement API methods (adjust base URL)"
|
|
154
|
+
echo " 3. Add stripSensitiveData() token cleanup"
|
|
155
|
+
echo " 4. Run: npm run build && npm test && npm run lint"
|
|
156
|
+
echo " 5. Add 'Getting Your API Token' to README.md"
|
|
157
|
+
;;
|
|
158
|
+
|
|
159
|
+
mcp-tool)
|
|
160
|
+
process_template "$TEMPLATE_DIR/mcp-tool.ts.tpl" "$PROJECT_ROOT/src/mcp/tools/$NAME.ts" && ((CREATED++)) || true
|
|
161
|
+
process_template "$TEMPLATE_DIR/mcp-tool-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/mcp/$NAME.test.ts" && ((CREATED++)) || true
|
|
162
|
+
|
|
163
|
+
echo ""
|
|
164
|
+
warn "Next steps:"
|
|
165
|
+
echo " 1. Register in src/mcp/server.ts:"
|
|
166
|
+
echo " registerTool('$NAME', { schema: ${NAME_CAMEL}Schema, handler: handle${NAME_PASCAL} })"
|
|
167
|
+
echo " 2. Define Zod schema (flat object, NOT z.object() wrapper)"
|
|
168
|
+
echo " 3. Handler delegates to core/ (NOT direct SSH/provider)"
|
|
169
|
+
echo " 4. Add SAFE_MODE check if destructive"
|
|
170
|
+
echo " 5. Run: npm run build && npm test && npm run lint"
|
|
171
|
+
echo " 6. Update README.md MCP tools table"
|
|
172
|
+
;;
|
|
173
|
+
esac
|
|
174
|
+
|
|
175
|
+
echo ""
|
|
176
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
177
|
+
info "[dry-run] No files were created."
|
|
178
|
+
else
|
|
179
|
+
ok "Scaffolded $CREATED file(s) for $TYPE: $NAME"
|
|
180
|
+
fi
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { parse__NAME_PASCAL__Checks } from "../../core/audit/checks/__NAME__.js";
|
|
2
|
-
|
|
3
|
-
describe("parse__NAME_PASCAL__Checks", () => {
|
|
4
|
-
beforeEach(() => jest.resetAllMocks());
|
|
5
|
-
|
|
6
|
-
it("returns checks when section output is valid", () => {
|
|
7
|
-
const result = parse__NAME_PASCAL__Checks("TODO_SENTINEL present", "linux");
|
|
8
|
-
expect(result.length).toBeGreaterThan(0);
|
|
9
|
-
expect(result[0].passed).toBe(true);
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it("returns empty array when section output is empty", () => {
|
|
13
|
-
const result = parse__NAME_PASCAL__Checks("", "linux");
|
|
14
|
-
expect(result).toEqual([]);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it("returns empty array when skip marker present", () => {
|
|
18
|
-
const result = parse__NAME_PASCAL__Checks("SKIP_MARKER", "linux");
|
|
19
|
-
expect(result).toEqual([]);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it("returns failed check when sentinel missing", () => {
|
|
23
|
-
const result = parse__NAME_PASCAL__Checks("some other output", "linux");
|
|
24
|
-
expect(result.length).toBeGreaterThan(0);
|
|
25
|
-
expect(result[0].passed).toBe(false);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
1
|
+
import { parse__NAME_PASCAL__Checks } from "../../core/audit/checks/__NAME__.js";
|
|
2
|
+
|
|
3
|
+
describe("parse__NAME_PASCAL__Checks", () => {
|
|
4
|
+
beforeEach(() => jest.resetAllMocks());
|
|
5
|
+
|
|
6
|
+
it("returns checks when section output is valid", () => {
|
|
7
|
+
const result = parse__NAME_PASCAL__Checks("TODO_SENTINEL present", "linux");
|
|
8
|
+
expect(result.length).toBeGreaterThan(0);
|
|
9
|
+
expect(result[0].passed).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("returns empty array when section output is empty", () => {
|
|
13
|
+
const result = parse__NAME_PASCAL__Checks("", "linux");
|
|
14
|
+
expect(result).toEqual([]);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("returns empty array when skip marker present", () => {
|
|
18
|
+
const result = parse__NAME_PASCAL__Checks("SKIP_MARKER", "linux");
|
|
19
|
+
expect(result).toEqual([]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("returns failed check when sentinel missing", () => {
|
|
23
|
+
const result = parse__NAME_PASCAL__Checks("some other output", "linux");
|
|
24
|
+
expect(result.length).toBeGreaterThan(0);
|
|
25
|
+
expect(result[0].passed).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
import type { AuditCheck, CheckParser } from "../../types.js";
|
|
2
|
-
|
|
3
|
-
interface __NAME_PASCAL__CheckDef {
|
|
4
|
-
id: string;
|
|
5
|
-
name: string;
|
|
6
|
-
severity: "critical" | "warning" | "info";
|
|
7
|
-
check: (output: string) => { passed: boolean; currentValue: string };
|
|
8
|
-
expectedValue: string;
|
|
9
|
-
fixCommand: string;
|
|
10
|
-
explain: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const __NAME_UPPER___CHECKS: __NAME_PASCAL__CheckDef[] = [
|
|
14
|
-
{
|
|
15
|
-
id: "__NAME_UPPER__-01",
|
|
16
|
-
name: "TODO: check description",
|
|
17
|
-
severity: "warning",
|
|
18
|
-
check: (output) => {
|
|
19
|
-
const match = output.includes("TODO_SENTINEL");
|
|
20
|
-
return { passed: match, currentValue: match ? "configured" : "not found" };
|
|
21
|
-
},
|
|
22
|
-
expectedValue: "configured",
|
|
23
|
-
fixCommand: "TODO: fix command",
|
|
24
|
-
explain: "TODO: why this matters",
|
|
25
|
-
},
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
export const parse__NAME_PASCAL__Checks: CheckParser = (
|
|
29
|
-
sectionOutput: string,
|
|
30
|
-
_platform: string,
|
|
31
|
-
): AuditCheck[] => {
|
|
32
|
-
if (!sectionOutput || sectionOutput.includes("SKIP_MARKER")) {
|
|
33
|
-
return [];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return __NAME_UPPER___CHECKS.map((def) => {
|
|
37
|
-
const { passed, currentValue } = def.check(sectionOutput);
|
|
38
|
-
return {
|
|
39
|
-
id: def.id,
|
|
40
|
-
category: "__NAME_PASCAL__",
|
|
41
|
-
name: def.name,
|
|
42
|
-
severity: def.severity,
|
|
43
|
-
passed,
|
|
44
|
-
currentValue,
|
|
45
|
-
expectedValue: def.expectedValue,
|
|
46
|
-
fixCommand: def.fixCommand,
|
|
47
|
-
explain: def.explain,
|
|
48
|
-
};
|
|
49
|
-
});
|
|
50
|
-
};
|
|
1
|
+
import type { AuditCheck, CheckParser } from "../../types.js";
|
|
2
|
+
|
|
3
|
+
interface __NAME_PASCAL__CheckDef {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
severity: "critical" | "warning" | "info";
|
|
7
|
+
check: (output: string) => { passed: boolean; currentValue: string };
|
|
8
|
+
expectedValue: string;
|
|
9
|
+
fixCommand: string;
|
|
10
|
+
explain: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const __NAME_UPPER___CHECKS: __NAME_PASCAL__CheckDef[] = [
|
|
14
|
+
{
|
|
15
|
+
id: "__NAME_UPPER__-01",
|
|
16
|
+
name: "TODO: check description",
|
|
17
|
+
severity: "warning",
|
|
18
|
+
check: (output) => {
|
|
19
|
+
const match = output.includes("TODO_SENTINEL");
|
|
20
|
+
return { passed: match, currentValue: match ? "configured" : "not found" };
|
|
21
|
+
},
|
|
22
|
+
expectedValue: "configured",
|
|
23
|
+
fixCommand: "TODO: fix command",
|
|
24
|
+
explain: "TODO: why this matters",
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
export const parse__NAME_PASCAL__Checks: CheckParser = (
|
|
29
|
+
sectionOutput: string,
|
|
30
|
+
_platform: string,
|
|
31
|
+
): AuditCheck[] => {
|
|
32
|
+
if (!sectionOutput || sectionOutput.includes("SKIP_MARKER")) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return __NAME_UPPER___CHECKS.map((def) => {
|
|
37
|
+
const { passed, currentValue } = def.check(sectionOutput);
|
|
38
|
+
return {
|
|
39
|
+
id: def.id,
|
|
40
|
+
category: "__NAME_PASCAL__",
|
|
41
|
+
name: def.name,
|
|
42
|
+
severity: def.severity,
|
|
43
|
+
passed,
|
|
44
|
+
currentValue,
|
|
45
|
+
expectedValue: def.expectedValue,
|
|
46
|
+
fixCommand: def.fixCommand,
|
|
47
|
+
explain: def.explain,
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
};
|