kastell 2.2.0 → 2.2.1
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 -0
- package/.claude-plugin/plugin.json +39 -0
- package/CHANGELOG.md +1266 -1266
- package/LICENSE +201 -201
- package/NOTICE +5 -5
- 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/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +4 -2
- package/dist/adapters/shared.js.map +1 -1
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +6 -9
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +12 -12
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/evidence.d.ts.map +1 -1
- package/dist/commands/evidence.js +8 -9
- package/dist/commands/evidence.js.map +1 -1
- package/dist/commands/fix.js +3 -3
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +4 -7
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/interactive/backup-maintenance.d.ts +8 -0
- package/dist/commands/interactive/backup-maintenance.d.ts.map +1 -0
- package/dist/commands/interactive/backup-maintenance.js +120 -0
- package/dist/commands/interactive/backup-maintenance.js.map +1 -0
- package/dist/commands/interactive/index.d.ts +4 -0
- package/dist/commands/interactive/index.d.ts.map +1 -0
- package/dist/commands/interactive/index.js +94 -0
- package/dist/commands/interactive/index.js.map +1 -0
- package/dist/commands/interactive/menu.d.ts +23 -0
- package/dist/commands/interactive/menu.d.ts.map +1 -0
- package/dist/commands/interactive/menu.js +121 -0
- package/dist/commands/interactive/menu.js.map +1 -0
- package/dist/commands/interactive/monitoring.d.ts +5 -0
- package/dist/commands/interactive/monitoring.d.ts.map +1 -0
- package/dist/commands/interactive/monitoring.js +96 -0
- package/dist/commands/interactive/monitoring.js.map +1 -0
- package/dist/commands/interactive/plugins.d.ts +2 -0
- package/dist/commands/interactive/plugins.d.ts.map +1 -0
- package/dist/commands/interactive/plugins.js +30 -0
- package/dist/commands/interactive/plugins.js.map +1 -0
- package/dist/commands/interactive/security.d.ts +9 -0
- package/dist/commands/interactive/security.d.ts.map +1 -0
- package/dist/commands/interactive/security.js +535 -0
- package/dist/commands/interactive/security.js.map +1 -0
- package/dist/commands/interactive/server-management.d.ts +5 -0
- package/dist/commands/interactive/server-management.d.ts.map +1 -0
- package/dist/commands/interactive/server-management.js +79 -0
- package/dist/commands/interactive/server-management.js.map +1 -0
- package/dist/commands/interactive/shared.d.ts +12 -0
- package/dist/commands/interactive/shared.d.ts.map +1 -0
- package/dist/commands/interactive/shared.js +30 -0
- package/dist/commands/interactive/shared.js.map +1 -0
- package/dist/commands/lock.js +1 -1
- package/dist/commands/lock.js.map +1 -1
- package/dist/commands/regression.d.ts.map +1 -1
- package/dist/commands/regression.js +1 -2
- package/dist/commands/regression.js.map +1 -1
- package/dist/commands/restart.d.ts.map +1 -1
- package/dist/commands/restart.js +3 -2
- package/dist/commands/restart.js.map +1 -1
- package/dist/commands/schedule.js +2 -2
- package/dist/commands/schedule.js.map +1 -1
- package/dist/core/audit/formatters/badge.js +20 -20
- package/dist/core/backup.d.ts.map +1 -1
- package/dist/core/backup.js +10 -5
- package/dist/core/backup.js.map +1 -1
- package/dist/core/completions.js +631 -631
- package/dist/core/deploy.d.ts.map +1 -1
- package/dist/core/deploy.js +7 -4
- package/dist/core/deploy.js.map +1 -1
- package/dist/core/lock/auth.d.ts +7 -0
- package/dist/core/lock/auth.d.ts.map +1 -0
- package/dist/core/lock/auth.js +59 -0
- package/dist/core/lock/auth.js.map +1 -0
- package/dist/core/lock/docker.d.ts +4 -0
- package/dist/core/lock/docker.d.ts.map +1 -0
- package/dist/core/lock/docker.js +28 -0
- package/dist/core/lock/docker.js.map +1 -0
- package/dist/core/lock/index.d.ts +11 -0
- package/dist/core/lock/index.d.ts.map +1 -0
- package/dist/core/lock/index.js +247 -0
- package/dist/core/lock/index.js.map +1 -0
- package/dist/core/lock/monitoring.d.ts +4 -0
- package/dist/core/lock/monitoring.d.ts.map +1 -0
- package/dist/core/lock/monitoring.js +55 -0
- package/dist/core/lock/monitoring.js.map +1 -0
- package/dist/core/lock/network.d.ts +6 -0
- package/dist/core/lock/network.d.ts.map +1 -0
- package/dist/core/lock/network.js +59 -0
- package/dist/core/lock/network.js.map +1 -0
- package/dist/core/lock/ssh.d.ts +5 -0
- package/dist/core/lock/ssh.d.ts.map +1 -0
- package/dist/core/lock/ssh.js +49 -0
- package/dist/core/lock/ssh.js.map +1 -0
- package/dist/core/lock/system.d.ts +9 -0
- package/dist/core/lock/system.d.ts.map +1 -0
- package/dist/core/lock/system.js +80 -0
- package/dist/core/lock/system.js.map +1 -0
- package/dist/core/lock/types.d.ts +41 -0
- package/dist/core/lock/types.d.ts.map +1 -0
- package/dist/core/lock/types.js +2 -0
- package/dist/core/lock/types.js.map +1 -0
- package/dist/core/maintain.d.ts.map +1 -1
- package/dist/core/maintain.js +3 -1
- package/dist/core/maintain.js.map +1 -1
- package/dist/core/manage.d.ts.map +1 -1
- package/dist/core/manage.js +5 -3
- package/dist/core/manage.js.map +1 -1
- package/dist/core/notifyStore.d.ts.map +1 -1
- package/dist/core/notifyStore.js +3 -1
- package/dist/core/notifyStore.js.map +1 -1
- package/dist/core/provision.d.ts.map +1 -1
- package/dist/core/provision.js +9 -4
- package/dist/core/provision.js.map +1 -1
- package/dist/core/scheduleManager.d.ts.map +1 -1
- package/dist/core/scheduleManager.js +5 -2
- package/dist/core/scheduleManager.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/schemas/audit.d.ts +34 -0
- package/dist/mcp/schemas/audit.d.ts.map +1 -0
- package/dist/mcp/schemas/audit.js +23 -0
- package/dist/mcp/schemas/audit.js.map +1 -0
- package/dist/mcp/schemas/common.d.ts +16 -0
- package/dist/mcp/schemas/common.d.ts.map +1 -0
- package/dist/mcp/schemas/common.js +14 -0
- package/dist/mcp/schemas/common.js.map +1 -0
- package/dist/mcp/schemas/health.d.ts +14 -0
- package/dist/mcp/schemas/health.d.ts.map +1 -0
- package/dist/mcp/schemas/health.js +13 -0
- package/dist/mcp/schemas/health.js.map +1 -0
- package/dist/mcp/schemas/index.d.ts +5 -0
- package/dist/mcp/schemas/index.d.ts.map +1 -0
- package/dist/mcp/schemas/index.js +5 -0
- package/dist/mcp/schemas/index.js.map +1 -0
- package/dist/mcp/schemas/server.d.ts +18 -0
- package/dist/mcp/schemas/server.d.ts.map +1 -0
- package/dist/mcp/schemas/server.js +16 -0
- package/dist/mcp/schemas/server.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +56 -39
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/serverAudit.d.ts +63 -1
- package/dist/mcp/tools/serverAudit.d.ts.map +1 -1
- package/dist/mcp/tools/serverAudit.js +63 -6
- package/dist/mcp/tools/serverAudit.js.map +1 -1
- package/dist/mcp/tools/serverBackup.d.ts +100 -2
- package/dist/mcp/tools/serverBackup.d.ts.map +1 -1
- package/dist/mcp/tools/serverBackup.handlers.d.ts.map +1 -1
- package/dist/mcp/tools/serverBackup.handlers.js +9 -0
- package/dist/mcp/tools/serverBackup.handlers.js.map +1 -1
- package/dist/mcp/tools/serverBackup.js +74 -0
- package/dist/mcp/tools/serverBackup.js.map +1 -1
- package/dist/mcp/tools/serverCompare.d.ts +33 -0
- package/dist/mcp/tools/serverCompare.d.ts.map +1 -1
- package/dist/mcp/tools/serverCompare.js +45 -2
- package/dist/mcp/tools/serverCompare.js.map +1 -1
- package/dist/mcp/tools/serverDoctor.d.ts +14 -0
- package/dist/mcp/tools/serverDoctor.d.ts.map +1 -1
- package/dist/mcp/tools/serverDoctor.js +15 -0
- package/dist/mcp/tools/serverDoctor.js.map +1 -1
- package/dist/mcp/tools/serverEvidence.d.ts +13 -0
- package/dist/mcp/tools/serverEvidence.d.ts.map +1 -1
- package/dist/mcp/tools/serverEvidence.js +17 -2
- package/dist/mcp/tools/serverEvidence.js.map +1 -1
- package/dist/mcp/tools/serverExplain.d.ts +17 -0
- package/dist/mcp/tools/serverExplain.d.ts.map +1 -1
- package/dist/mcp/tools/serverExplain.js +33 -1
- package/dist/mcp/tools/serverExplain.js.map +1 -1
- package/dist/mcp/tools/serverFix.d.ts +78 -0
- package/dist/mcp/tools/serverFix.d.ts.map +1 -1
- package/dist/mcp/tools/serverFix.js +84 -0
- package/dist/mcp/tools/serverFix.js.map +1 -1
- package/dist/mcp/tools/serverFleet.d.ts +24 -1
- package/dist/mcp/tools/serverFleet.d.ts.map +1 -1
- package/dist/mcp/tools/serverFleet.js +24 -1
- package/dist/mcp/tools/serverFleet.js.map +1 -1
- package/dist/mcp/tools/serverGuard.d.ts +12 -0
- package/dist/mcp/tools/serverGuard.d.ts.map +1 -1
- package/dist/mcp/tools/serverGuard.js +16 -0
- package/dist/mcp/tools/serverGuard.js.map +1 -1
- package/dist/mcp/tools/serverInfo.d.ts +77 -1
- package/dist/mcp/tools/serverInfo.d.ts.map +1 -1
- package/dist/mcp/tools/serverInfo.js +77 -4
- package/dist/mcp/tools/serverInfo.js.map +1 -1
- package/dist/mcp/tools/serverLock.d.ts +10 -0
- package/dist/mcp/tools/serverLock.d.ts.map +1 -1
- package/dist/mcp/tools/serverLock.js +15 -3
- package/dist/mcp/tools/serverLock.js.map +1 -1
- package/dist/mcp/tools/serverLogs.d.ts +43 -0
- package/dist/mcp/tools/serverLogs.d.ts.map +1 -1
- package/dist/mcp/tools/serverLogs.js +28 -0
- package/dist/mcp/tools/serverLogs.js.map +1 -1
- package/dist/mcp/tools/serverMaintain.d.ts +47 -0
- package/dist/mcp/tools/serverMaintain.d.ts.map +1 -1
- package/dist/mcp/tools/serverMaintain.js +75 -41
- package/dist/mcp/tools/serverMaintain.js.map +1 -1
- package/dist/mcp/tools/serverManage.d.ts +50 -0
- package/dist/mcp/tools/serverManage.d.ts.map +1 -1
- package/dist/mcp/tools/serverManage.js +49 -0
- package/dist/mcp/tools/serverManage.js.map +1 -1
- package/dist/mcp/tools/serverPlugin.d.ts +18 -0
- package/dist/mcp/tools/serverPlugin.d.ts.map +1 -1
- package/dist/mcp/tools/serverPlugin.js +26 -1
- package/dist/mcp/tools/serverPlugin.js.map +1 -1
- package/dist/mcp/tools/serverProvision.d.ts +22 -0
- package/dist/mcp/tools/serverProvision.d.ts.map +1 -1
- package/dist/mcp/tools/serverProvision.js +22 -2
- package/dist/mcp/tools/serverProvision.js.map +1 -1
- package/dist/mcp/tools/serverSecure.d.ts +120 -0
- package/dist/mcp/tools/serverSecure.d.ts.map +1 -1
- package/dist/mcp/tools/serverSecure.handlers.d.ts.map +1 -1
- package/dist/mcp/tools/serverSecure.handlers.js +39 -98
- package/dist/mcp/tools/serverSecure.handlers.js.map +1 -1
- package/dist/mcp/tools/serverSecure.js +101 -0
- package/dist/mcp/tools/serverSecure.js.map +1 -1
- package/dist/mcp/utils.d.ts +1 -0
- package/dist/mcp/utils.d.ts.map +1 -1
- package/dist/mcp/utils.js +5 -1
- package/dist/mcp/utils.js.map +1 -1
- package/dist/plugin/registry.d.ts.map +1 -1
- package/dist/plugin/registry.js +5 -3
- package/dist/plugin/registry.js.map +1 -1
- package/dist/providers/linode.d.ts +1 -0
- package/dist/providers/linode.d.ts.map +1 -1
- package/dist/providers/linode.js +4 -0
- package/dist/providers/linode.js.map +1 -1
- package/dist/utils/cloudInit.js +58 -58
- package/dist/utils/config.d.ts +3 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +11 -6
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/encryption.d.ts.map +1 -1
- package/dist/utils/encryption.js +4 -1
- package/dist/utils/encryption.js.map +1 -1
- package/dist/utils/migration.d.ts.map +1 -1
- package/dist/utils/migration.js +25 -14
- package/dist/utils/migration.js.map +1 -1
- package/dist/utils/safeMode.d.ts.map +1 -1
- package/dist/utils/safeMode.js +3 -2
- package/dist/utils/safeMode.js.map +1 -1
- package/dist/utils/securityLogger.d.ts.map +1 -1
- package/dist/utils/securityLogger.js +7 -3
- package/dist/utils/securityLogger.js.map +1 -1
- package/kastell-plugin/.claude-plugin/plugin.json +20 -0
- package/kastell-plugin/.mcp.json +8 -0
- package/kastell-plugin/README.md +113 -0
- package/kastell-plugin/agents/.gitkeep +0 -0
- package/kastell-plugin/agents/kastell-auditor.md +77 -0
- package/kastell-plugin/agents/scripts/bucket_mapper.sh +101 -0
- package/kastell-plugin/agents/scripts/trend_report.sh +91 -0
- package/kastell-plugin/hooks/destroy-block.cjs +31 -0
- package/kastell-plugin/hooks/hooks.json +57 -0
- package/kastell-plugin/hooks/pre-commit-audit-guard.cjs +75 -0
- package/kastell-plugin/hooks/session-audit.cjs +86 -0
- package/kastell-plugin/hooks/session-log.cjs +56 -0
- package/kastell-plugin/hooks/stop-quality-check.cjs +72 -0
- package/kastell-plugin/skills/.gitkeep +0 -0
- package/kastell-plugin/skills/kastell-careful/SKILL.md +64 -0
- package/kastell-plugin/skills/kastell-ops/SKILL.md +139 -0
- package/kastell-plugin/skills/kastell-ops/references/commands.md +45 -0
- package/kastell-plugin/skills/kastell-ops/references/mcp-tools.md +50 -0
- package/kastell-plugin/skills/kastell-ops/references/patterns.md +145 -0
- package/kastell-plugin/skills/kastell-ops/references/pitfalls.md +136 -0
- package/kastell-plugin/skills/kastell-ops/scripts/check_coverage.sh +101 -0
- package/kastell-plugin/skills/kastell-ops/scripts/fleet_report.sh +73 -0
- package/kastell-plugin/skills/kastell-ops/scripts/parse_audit.sh +76 -0
- package/kastell-plugin/skills/kastell-research/SKILL.md +90 -0
- package/kastell-plugin/skills/kastell-scaffold/SKILL.md +104 -0
- package/kastell-plugin/skills/kastell-scaffold/references/template-audit-check.md +150 -0
- package/kastell-plugin/skills/kastell-scaffold/references/template-command.md +80 -0
- package/kastell-plugin/skills/kastell-scaffold/references/template-mcp-tool.md +72 -0
- package/kastell-plugin/skills/kastell-scaffold/references/template-provider.md +67 -0
- package/kastell-plugin/skills/kastell-scaffold/scripts/scaffold.sh +180 -0
- package/kastell-plugin/skills/kastell-scaffold/templates/check-test.ts.tpl +27 -0
- package/kastell-plugin/skills/kastell-scaffold/templates/check.ts.tpl +50 -0
- package/kastell-plugin/skills/kastell-scaffold/templates/command-core.ts.tpl +18 -0
- package/kastell-plugin/skills/kastell-scaffold/templates/command-test.ts.tpl +17 -0
- package/kastell-plugin/skills/kastell-scaffold/templates/command.ts.tpl +25 -0
- package/kastell-plugin/skills/kastell-scaffold/templates/mcp-tool-test.ts.tpl +30 -0
- package/kastell-plugin/skills/kastell-scaffold/templates/mcp-tool.ts.tpl +29 -0
- package/kastell-plugin/skills/kastell-scaffold/templates/provider-test.ts.tpl +34 -0
- package/kastell-plugin/skills/kastell-scaffold/templates/provider.ts.tpl +32 -0
- package/package.json +122 -115
|
@@ -0,0 +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
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface __NAME_PASCAL__Options {
|
|
2
|
+
server?: string;
|
|
3
|
+
json?: boolean;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface __NAME_PASCAL__Result {
|
|
7
|
+
success: boolean;
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function __NAME_CAMEL__Core(
|
|
12
|
+
options: __NAME_PASCAL__Options,
|
|
13
|
+
): Promise<__NAME_PASCAL__Result> {
|
|
14
|
+
// ALL business logic here. NO chalk/ora/UI imports.
|
|
15
|
+
// assertValidIp() before SSH. getAdapter(platform) for platform ops.
|
|
16
|
+
// withProviderErrorHandling() for provider calls.
|
|
17
|
+
throw new Error("Not implemented");
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { __NAME_CAMEL__Core } from "../../core/__NAME__.js";
|
|
2
|
+
|
|
3
|
+
jest.mock("../../utils/ssh.js");
|
|
4
|
+
|
|
5
|
+
describe("__NAME_CAMEL__Core", () => {
|
|
6
|
+
beforeEach(() => jest.resetAllMocks());
|
|
7
|
+
|
|
8
|
+
it("should TODO: describe expected behavior", async () => {
|
|
9
|
+
const result = await __NAME_CAMEL__Core({ server: "test-server" });
|
|
10
|
+
expect(result.success).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("should handle missing server gracefully", async () => {
|
|
14
|
+
const result = await __NAME_CAMEL__Core({});
|
|
15
|
+
expect(result.success).toBe(false);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { program } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import ora from "ora";
|
|
4
|
+
import { __NAME_CAMEL__Core } from "../core/__NAME__.js";
|
|
5
|
+
|
|
6
|
+
program
|
|
7
|
+
.command("__NAME__")
|
|
8
|
+
.description("TODO: describe what this command does")
|
|
9
|
+
.option("--server <name>", "Target server name or IP")
|
|
10
|
+
.option("--json", "Output as JSON")
|
|
11
|
+
.action(async (options) => {
|
|
12
|
+
const spinner = ora("Running __NAME__...").start();
|
|
13
|
+
try {
|
|
14
|
+
const result = await __NAME_CAMEL__Core(options);
|
|
15
|
+
spinner.succeed("Done");
|
|
16
|
+
if (options.json) {
|
|
17
|
+
console.log(JSON.stringify(result, null, 2));
|
|
18
|
+
} else {
|
|
19
|
+
console.log(chalk.green(result.message));
|
|
20
|
+
}
|
|
21
|
+
} catch (error) {
|
|
22
|
+
spinner.fail(error instanceof Error ? error.message : "Unknown error");
|
|
23
|
+
process.exitCode = 1;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { handle__NAME_PASCAL__ } from "../../mcp/tools/__NAME__.js";
|
|
2
|
+
|
|
3
|
+
// Mock the core dependency
|
|
4
|
+
// jest.mock("../../core/__NAME__.js");
|
|
5
|
+
|
|
6
|
+
describe("handle__NAME_PASCAL__", () => {
|
|
7
|
+
beforeEach(() => jest.resetAllMocks());
|
|
8
|
+
|
|
9
|
+
it("returns success response", async () => {
|
|
10
|
+
const result = await handle__NAME_PASCAL__({
|
|
11
|
+
server: "test-server",
|
|
12
|
+
action: "TODO",
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
expect(result.isError).toBeUndefined();
|
|
16
|
+
expect(result.content[0].text).toContain("success");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("handles missing server gracefully", async () => {
|
|
20
|
+
const result = await handle__NAME_PASCAL__({
|
|
21
|
+
action: "TODO",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(result.content).toBeDefined();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("returns error on failure", async () => {
|
|
28
|
+
// TODO: mock core to reject, verify isError
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpResponse } from "../types.js";
|
|
3
|
+
|
|
4
|
+
// IMPORTANT: Schema is a flat object, NOT wrapped in z.object()
|
|
5
|
+
// The SDK wraps it automatically
|
|
6
|
+
export const __NAME_CAMEL__Schema = {
|
|
7
|
+
server: z
|
|
8
|
+
.string()
|
|
9
|
+
.optional()
|
|
10
|
+
.describe("Server name or IP. Auto-selected if only one server exists."),
|
|
11
|
+
action: z.enum(["TODO"]).describe("TODO: describe actions"),
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export async function handle__NAME_PASCAL__(params: {
|
|
15
|
+
server?: string;
|
|
16
|
+
action: string;
|
|
17
|
+
}): Promise<McpResponse> {
|
|
18
|
+
// Delegate to core function (NOT direct SSH/provider calls)
|
|
19
|
+
// Example: const result = await someCoreFunction(params);
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
content: [
|
|
23
|
+
{
|
|
24
|
+
type: "text" as const,
|
|
25
|
+
text: JSON.stringify({ success: true }, null, 2),
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { __NAME_PASCAL__Provider } from "../../providers/__NAME__.js";
|
|
2
|
+
|
|
3
|
+
// Mock axios at module level
|
|
4
|
+
jest.mock("axios", () => ({
|
|
5
|
+
create: jest.fn(() => ({
|
|
6
|
+
get: jest.fn(),
|
|
7
|
+
post: jest.fn(),
|
|
8
|
+
delete: jest.fn(),
|
|
9
|
+
})),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
describe("__NAME_PASCAL__Provider", () => {
|
|
13
|
+
let provider: __NAME_PASCAL__Provider;
|
|
14
|
+
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
jest.resetAllMocks();
|
|
17
|
+
provider = new __NAME_PASCAL__Provider("test-token");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("should create instance with correct base URL", () => {
|
|
21
|
+
expect(provider).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should list servers", async () => {
|
|
25
|
+
// TODO: mock API response and verify
|
|
26
|
+
await expect(provider.listServers()).resolves.toBeDefined();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should create server", async () => {
|
|
30
|
+
// TODO: mock API response and verify
|
|
31
|
+
const params = { name: "test", region: "us-east", size: "small" };
|
|
32
|
+
await expect(provider.createServer(params)).resolves.toBeDefined();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseProvider,
|
|
3
|
+
type ProviderServer,
|
|
4
|
+
type CreateServerParams,
|
|
5
|
+
type ProviderResponse,
|
|
6
|
+
} from "./base.js";
|
|
7
|
+
|
|
8
|
+
export class __NAME_PASCAL__Provider extends BaseProvider {
|
|
9
|
+
constructor(token: string) {
|
|
10
|
+
super(token, "https://api.__NAME__.com/v1"); // TODO: adjust API base URL
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async listServers(): Promise<ProviderResponse<ProviderServer[]>> {
|
|
14
|
+
return this.request<ProviderServer[]>("GET", "/servers");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async createServer(
|
|
18
|
+
params: CreateServerParams,
|
|
19
|
+
): Promise<ProviderResponse<ProviderServer>> {
|
|
20
|
+
return this.request<ProviderServer>("POST", "/servers", { body: params });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async deleteServer(serverId: string): Promise<ProviderResponse<void>> {
|
|
24
|
+
return this.request<void>("DELETE", `/servers/${serverId}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async getServer(
|
|
28
|
+
serverId: string,
|
|
29
|
+
): Promise<ProviderResponse<ProviderServer>> {
|
|
30
|
+
return this.request<ProviderServer>("GET", `/servers/${serverId}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
package/package.json
CHANGED
|
@@ -1,115 +1,122 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "kastell",
|
|
3
|
-
"version": "2.2.
|
|
4
|
-
"description": "CLI toolkit for provisioning, securing, and managing self-hosted servers",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"bin": {
|
|
8
|
-
"kastell": "bin/kastell",
|
|
9
|
-
"kastell-mcp": "bin/kastell-mcp"
|
|
10
|
-
},
|
|
11
|
-
"files": [
|
|
12
|
-
"bin/",
|
|
13
|
-
"dist/",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
"
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"@
|
|
101
|
-
"@
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
|
|
115
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "kastell",
|
|
3
|
+
"version": "2.2.1",
|
|
4
|
+
"description": "CLI toolkit for provisioning, securing, and managing self-hosted servers",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"kastell": "bin/kastell",
|
|
9
|
+
"kastell-mcp": "bin/kastell-mcp"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin/",
|
|
13
|
+
"dist/",
|
|
14
|
+
".claude-plugin/",
|
|
15
|
+
"kastell-plugin/skills/",
|
|
16
|
+
"kastell-plugin/agents/",
|
|
17
|
+
"kastell-plugin/hooks/",
|
|
18
|
+
"kastell-plugin/.claude-plugin/",
|
|
19
|
+
"kastell-plugin/.mcp.json",
|
|
20
|
+
"kastell-plugin/README.md",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"NOTICE",
|
|
24
|
+
"SECURITY.md",
|
|
25
|
+
"CHANGELOG.md"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"dev": "tsx src/index.ts",
|
|
29
|
+
"build": "tsc",
|
|
30
|
+
"start": "node dist/index.js",
|
|
31
|
+
"test": "jest --config jest.config.cjs",
|
|
32
|
+
"test:watch": "jest --config jest.config.cjs --watch",
|
|
33
|
+
"test:coverage": "jest --config jest.config.cjs --coverage",
|
|
34
|
+
"test:mutate": "cp .stryker-tmp/incremental.json .stryker-tmp/incremental.backup.json 2>/dev/null; stryker run",
|
|
35
|
+
"lint": "eslint src/",
|
|
36
|
+
"lint:fix": "eslint src/ --fix",
|
|
37
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
38
|
+
"format:check": "prettier --check \"src/**/*.ts\""
|
|
39
|
+
},
|
|
40
|
+
"mcpName": "io.github.kastelldev/kastell",
|
|
41
|
+
"keywords": [
|
|
42
|
+
"kastell",
|
|
43
|
+
"mcp-server",
|
|
44
|
+
"coolify",
|
|
45
|
+
"deployment",
|
|
46
|
+
"hetzner",
|
|
47
|
+
"digitalocean",
|
|
48
|
+
"vultr",
|
|
49
|
+
"linode",
|
|
50
|
+
"cli",
|
|
51
|
+
"vps",
|
|
52
|
+
"cloud",
|
|
53
|
+
"automation",
|
|
54
|
+
"self-hosted",
|
|
55
|
+
"server-security",
|
|
56
|
+
"server-maintenance",
|
|
57
|
+
"infrastructure",
|
|
58
|
+
"devops",
|
|
59
|
+
"server"
|
|
60
|
+
],
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=20.0.0"
|
|
63
|
+
},
|
|
64
|
+
"license": "Apache-2.0",
|
|
65
|
+
"repository": {
|
|
66
|
+
"type": "git",
|
|
67
|
+
"url": "https://github.com/kastelldev/kastell.git"
|
|
68
|
+
},
|
|
69
|
+
"bugs": {
|
|
70
|
+
"url": "https://github.com/kastelldev/kastell/issues"
|
|
71
|
+
},
|
|
72
|
+
"homepage": "https://kastell.dev",
|
|
73
|
+
"author": {
|
|
74
|
+
"name": "Ömer",
|
|
75
|
+
"email": "hello@omrfc.dev",
|
|
76
|
+
"url": "https://omrfc.dev"
|
|
77
|
+
},
|
|
78
|
+
"funding": {
|
|
79
|
+
"type": "github",
|
|
80
|
+
"url": "https://github.com/sponsors/omrfc"
|
|
81
|
+
},
|
|
82
|
+
"dependencies": {
|
|
83
|
+
"@modelcontextprotocol/sdk": "1.27.1",
|
|
84
|
+
"@napi-rs/keyring": "1.2.0",
|
|
85
|
+
"axios": "1.15.0",
|
|
86
|
+
"chalk": "5.6.2",
|
|
87
|
+
"commander": "14.0.3",
|
|
88
|
+
"grammy": "1.41.1",
|
|
89
|
+
"inquirer": "12.11.1",
|
|
90
|
+
"js-yaml": "4.1.1",
|
|
91
|
+
"ora": "9.3.0",
|
|
92
|
+
"p-limit": "7.3.0",
|
|
93
|
+
"semver": "7.7.2",
|
|
94
|
+
"zod": "4.3.6"
|
|
95
|
+
},
|
|
96
|
+
"overrides": {
|
|
97
|
+
"minimatch": "^10.2.4"
|
|
98
|
+
},
|
|
99
|
+
"devDependencies": {
|
|
100
|
+
"@eslint/js": "^10.0.1",
|
|
101
|
+
"@stryker-mutator/core": "^9.6.0",
|
|
102
|
+
"@stryker-mutator/jest-runner": "^9.6.0",
|
|
103
|
+
"@stryker-mutator/typescript-checker": "^9.6.0",
|
|
104
|
+
"@types/inquirer": "^9.0.7",
|
|
105
|
+
"@types/jest": "^30.0.0",
|
|
106
|
+
"@types/js-yaml": "^4.0.9",
|
|
107
|
+
"@types/node": "^22.12.0",
|
|
108
|
+
"@types/semver": "7.7.0",
|
|
109
|
+
"eslint": "^10.0.2",
|
|
110
|
+
"eslint-config-prettier": "^10.1.8",
|
|
111
|
+
"eslint-plugin-no-secrets": "^2.3.3",
|
|
112
|
+
"eslint-plugin-security": "^4.0.0",
|
|
113
|
+
"fast-check": "^4.7.0",
|
|
114
|
+
"ignore": "^7.0.5",
|
|
115
|
+
"jest": "^30.2.0",
|
|
116
|
+
"prettier": "^3.8.1",
|
|
117
|
+
"ts-jest": "^29.4.6",
|
|
118
|
+
"tsx": "^4.21.0",
|
|
119
|
+
"typescript": "^5.9.3",
|
|
120
|
+
"typescript-eslint": "^8.56.1"
|
|
121
|
+
}
|
|
122
|
+
}
|