kastell 1.15.0 → 1.15.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/CHANGELOG.md +1056 -0
- package/README.md +28 -11
- package/README.tr.md +27 -10
- package/dist/commands/changelog.d.ts +4 -0
- package/dist/commands/changelog.d.ts.map +1 -0
- package/dist/commands/changelog.js +11 -0
- package/dist/commands/changelog.js.map +1 -0
- package/dist/commands/interactive.d.ts.map +1 -1
- package/dist/commands/interactive.js +2 -1
- package/dist/commands/interactive.js.map +1 -1
- package/dist/core/audit/checks/backup.js +1 -1
- package/dist/core/audit/checks/backup.js.map +1 -1
- package/dist/core/audit/checks/boot.js +1 -1
- package/dist/core/audit/checks/boot.js.map +1 -1
- package/dist/core/audit/checks/incidentready.js +1 -1
- package/dist/core/audit/checks/incidentready.js.map +1 -1
- package/dist/core/audit/checks/logging.js +1 -1
- package/dist/core/audit/checks/logging.js.map +1 -1
- package/dist/core/audit/fix.js +2 -2
- package/dist/core/audit/fix.js.map +1 -1
- package/dist/core/bot/middleware.js +1 -1
- package/dist/core/bot/middleware.js.map +1 -1
- package/dist/core/changelog.d.ts +18 -0
- package/dist/core/changelog.d.ts.map +1 -0
- package/dist/core/changelog.js +93 -0
- package/dist/core/changelog.js.map +1 -0
- package/dist/core/doctor.js +1 -1
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/notify.d.ts.map +1 -1
- package/dist/core/notify.js +4 -0
- package/dist/core/notify.js.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.js +5 -0
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/tools/serverInfo.d.ts.map +1 -1
- package/dist/mcp/tools/serverInfo.js +4 -1
- package/dist/mcp/tools/serverInfo.js.map +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/ssh.d.ts.map +1 -1
- package/dist/utils/ssh.js +12 -2
- package/dist/utils/ssh.js.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,1056 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.15.1] - 2026-03-28
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **`kastell changelog` command** — Parse and display CHANGELOG.md in terminal (`kastell changelog`, `kastell changelog v1.14.0`, `kastell changelog --all`)
|
|
9
|
+
- **"Why Kastell?" manifesto** in README (EN + TR) — problem statement, approach, AI-native positioning
|
|
10
|
+
- **Kastell vs Alternatives comparison table** in README (EN + TR) — Kastell vs Lynis vs OpenSCAP across 12 dimensions
|
|
11
|
+
- **Zero Telemetry badge** in README (EN + TR) — trust signal, no data collection
|
|
12
|
+
- **CI profile stats dispatch** — `.github` org profile auto-updates on every main push (test/check/category/MCP counts)
|
|
13
|
+
- Interactive menu: "View changelog" entry in Configuration section
|
|
14
|
+
- CHANGELOG.md included in npm package files
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- **sshExec SSH banner handling** — servers with login banners caused non-zero exit codes on Windows, breaking health checks, audit scores (42→11 false drop), and doctor cache writes. Now checks stdout content when stderr is banner-only
|
|
18
|
+
- **3 incorrect fix commands** — `grub2-mkpasswd-pbkdf2` → `grub-mkpasswd-pbkdf2` (Ubuntu), `dc3dd` → `sleuthkit` (available in repos), `vector` → `rsyslog` (no 3rd party repo needed)
|
|
19
|
+
- **Backup fix command** — `kastell backup create` (local CLI, not available on server) → server-side `tar` command
|
|
20
|
+
- **audit-watch test timeout** — Windows CI fake timer slowness (jest.setTimeout 15s + extra microtick flushes)
|
|
21
|
+
- **CI dispatch format** — JSON body for repository_dispatch (was form-encoded)
|
|
22
|
+
|
|
23
|
+
### Security
|
|
24
|
+
- 10 security audit remediation items applied: SHELL_METACHAR validation, bot middleware fail-closed, clearKnownHostKey IP validation, sendTelegram token validation, unhandled rejection handler, npm publish --provenance, staging token scope, debugLog→KASTELL_DEBUG
|
|
25
|
+
- Security audit report: `security-audit-report.md` (39 findings, 0 critical)
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- Test count: 5,506 → 5,522 (16 new tests: 4 SSH banner + 12 changelog)
|
|
29
|
+
- Test suites: 206 → 207
|
|
30
|
+
|
|
31
|
+
## [1.15.0] - 2026-03-27
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **Edge & WAF Audit (P88):** 9 Nginx config checks + WAF detection, 30th audit category, CIS/PCI-DSS compliance mapping
|
|
35
|
+
- **TCP Stack DDoS Hardening (P89):** 8 sysctl DDoS parameter checks, 31st audit category, Docker platform guard
|
|
36
|
+
- **kastell fix --safe (P90):** SAFE/GUARDED/FORBIDDEN tier classification for 442+ checks, mandatory backup, dry-run, fix→verify pipeline
|
|
37
|
+
- **MCP server_fix (P91):** 14th MCP tool with dryRun:true default, SAFE_MODE guard, TypeScript FORBIDDEN rejection
|
|
38
|
+
- **Telegram Bot Notifications (P92):** Guard audit score monitoring, two-tier alerts (warning 5-9pt, critical 10+pt), 24h staleness guard, allowedChatIds CRUD
|
|
39
|
+
- **Telegram Bot Commands (P93):** grammy polling bot with /status, /audit, /health, /doctor, /help commands, allowedChatIds middleware, offset persistence
|
|
40
|
+
- `kastell bot start` command for foreground Telegram bot
|
|
41
|
+
- Interactive menu: "Start Telegram bot" entry in Notifications & Bot section
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
- Audit categories: 29 → 31 (WAF & Reverse Proxy, DDoS Hardening)
|
|
45
|
+
- Audit checks: 413 → 442
|
|
46
|
+
- Test count: 5468 → 5499 (31 new bot module tests)
|
|
47
|
+
- Interactive menu audit description updated to 31 categories
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
- npm audit vulnerabilities fixed (brace-expansion, handlebars, picomatch)
|
|
51
|
+
|
|
52
|
+
### Security
|
|
53
|
+
- Bot allowedChatIds middleware silently blocks unauthorized users (no response leaked)
|
|
54
|
+
- Offset persistence prevents stale command replay on bot restart
|
|
55
|
+
- server_fix FORBIDDEN rejection blocks SSH/Firewall/Docker category fixes via MCP
|
|
56
|
+
- Fix tier classification: SSH/Firewall changes always FORBIDDEN (never auto-fixed)
|
|
57
|
+
|
|
58
|
+
## [1.14.0] - 2026-03-24
|
|
59
|
+
|
|
60
|
+
### Added
|
|
61
|
+
- **Snapshot Restore** — `kastell snapshot restore` CLI + MCP `snapshot-restore` action with SAFE_MODE guard, double confirmation, and 4-provider support (Hetzner, DigitalOcean, Vultr, Linode)
|
|
62
|
+
- **Cloud ID Lookup** — `findServerByIp()` across all 4 providers; `kastell add` now displays Cloud ID automatically
|
|
63
|
+
- **TLS Hardening Audit** — 8 checks (min version, weak ciphers, HSTS with max-age validation, OCSP stapling, cert expiry, DH params, compression, cert chain) with PCI-DSS/CIS/HIPAA compliance mappings
|
|
64
|
+
- **HTTP Security Headers Audit** — 6 checks (X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, CORS wildcard, CSP) with PCI-DSS v4.0 mappings
|
|
65
|
+
- **Lock Score Boost** — 4 new lock steps (SSH fine-tuning with 15 directives, login.defs hardening, pam_faillock, sudo logging/requiretty) + 2 extended steps (banners +/etc/motd, cronAccess +at.allow); 24-step orchestrator
|
|
66
|
+
- **Interactive menu** — Added snapshot restore, audit --explain/--diff/--fix, doctor --fix options
|
|
67
|
+
- **Stryker Mutation Testing** — Baseline 40.74% across 19,726 mutants
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
- **Lock-audit alignment** — 5 misalignments fixed (AIDE cron path, auditd restart, logrotate install+timer, cronAccess step, Docker mkdir)
|
|
71
|
+
- **snapshotId MCP validation** — Added regex validation for defense-in-depth
|
|
72
|
+
- **CERT_NOT_FOUND sentinel** — Properly emits when certificate file is missing instead of false CERT_EXPIRING_SOON
|
|
73
|
+
- **HTTPS-only audit gap** — HTTP header audit now tries HTTPS before HTTP for HTTPS-only servers
|
|
74
|
+
- **CLI snapshotCreate SAFE_MODE** — Added guard for consistency with MCP handler
|
|
75
|
+
- **Vultr/Linode snapshotId validation** — Added `assertValidServerId` for defense-in-depth
|
|
76
|
+
- **Hetzner findServerByIp pagination** — Changed `per_page` from 50 to 100 for consistency
|
|
77
|
+
- **Faillock idempotency** — Each directive independently checked/updated instead of batch
|
|
78
|
+
- **fileLock ENOENT** — Ensure parent directory exists before creating lock file
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
- **Test suite** — 4178→5087 tests (909 new), 197 suites, 11 snapshots; branch coverage: global 93.25%, audit 95.96%, providers 91.22%, MCP 90.25%
|
|
82
|
+
- **Audit categories** — 27→29 (TLS Hardening + HTTP Security Headers); 421+ total checks
|
|
83
|
+
- **CI hardening** — Codecov integration, 4 typed test factory helpers, zero `as any` casts (231→0)
|
|
84
|
+
- **CI release gate** — `release.yml` now depends on CI success via `workflow_run` (prevents releasing when CI fails)
|
|
85
|
+
- **CI tag support** — CI workflow now runs on tag pushes for release/publish chain
|
|
86
|
+
- **TLS weak cipher detection** — Added SEED and IDEA to pattern
|
|
87
|
+
- **HSTS validation** — Now checks max-age >= 31536000
|
|
88
|
+
- **Compliance mappings** — Added HIPAA for TLS, updated PCI-DSS HDR-005 to v4.0 (6.2.4)
|
|
89
|
+
- **Skill consolidation** — 5 global security skills delegated to single `kastell-security-check.md`
|
|
90
|
+
|
|
91
|
+
### Removed
|
|
92
|
+
- **Stryker from CI** — Mutation testing removed from GitHub Actions (exceeds 6h limit); moved to dedicated infrastructure with scheduled nightly incremental runs
|
|
93
|
+
|
|
94
|
+
### Security
|
|
95
|
+
- **Comprehensive v1.14 review** — 5-agent parallel audit (OWASP, token/secret, audit system, code quality, test coverage); 13 findings resolved (3 MEDIUM + 10 LOW)
|
|
96
|
+
- **Release workflow injection fix** — Prevented shell injection via `head_branch` interpolation; added strict semver validation before checkout
|
|
97
|
+
- **Zero token leakage** — 5-layer sanitization verified across all new code paths
|
|
98
|
+
|
|
99
|
+
## [1.13.0] - 2026-03-19
|
|
100
|
+
|
|
101
|
+
### Added
|
|
102
|
+
- **Claude Code Plugin** — `kastell-plugin/` marketplace-ready package with `plugin.json` manifest, `.mcp.json`, and `hooks.json`
|
|
103
|
+
- **4 Skills** — `kastell-ops` (background server management), `kastell-research` (Explore agent + architecture map), `kastell-careful` (skill-scoped LLM prompt hook), `kastell-scaffold` (4 fork-friendly templates)
|
|
104
|
+
- **2 Agents** — `kastell-auditor` (security review) and `kastell-fixer` (bug diagnosis) project-scope agents
|
|
105
|
+
- **5 Hooks** — `session-log`, `stop-quality-check`, `session-audit`, `pre-commit-audit-guard`, `destroy-block` with ESM-compatible `.cjs` scripts
|
|
106
|
+
- **MCP Discoverability** — `server.instructions`, MCP Logging, `llms.txt`, `SUBMISSIONS.md`, 4 platform setup guides, `mcp-server` keyword
|
|
107
|
+
- **Dynamic Content Injection** — `!command` syntax in 4 skill files for live codebase context
|
|
108
|
+
|
|
109
|
+
### Fixed
|
|
110
|
+
- **CLI↔MCP parity** — 3 bugs fixed: logs default service (Dokploy), health host-key-mismatch detection, maintain update validation
|
|
111
|
+
- **DO Coolify SSH key loss** — Re-inject SSH public key after platform installer in cloud-init
|
|
112
|
+
- **Docker crash after lock** — SSH host key resolution in MCP health checks
|
|
113
|
+
- **Plugin hook ESM compatibility** — Renamed `.js` → `.cjs` for ESM project compatibility
|
|
114
|
+
|
|
115
|
+
### Changed
|
|
116
|
+
- **Commands→Core extraction** — `backup`, `status`, `update` business logic moved from commands/ to core/ (thin command pattern)
|
|
117
|
+
- **Adapter bypass elimination** — 9 commands now use adapter properties (`port`, `defaultLogService`, `platformPorts`) instead of hardcoded values
|
|
118
|
+
- **Shared `createMockAdapter()`** — Test mock factory in `tests/helpers/mockAdapter.ts`; deduplicated across all test files
|
|
119
|
+
- **Test coverage** — 4156→4178 tests (adapter contract, core extraction, hook tests)
|
|
120
|
+
|
|
121
|
+
## [1.12.0] - 2026-03-18
|
|
122
|
+
|
|
123
|
+
### Added
|
|
124
|
+
- **`audit --explain`** — Inline "Why:" + fix explanation for each failing check in CLI and MCP (`--explain` flag, 95%+ coverage)
|
|
125
|
+
- **Lock: auditd CIS L2 rules** — Deep audit rules (time-change, network-change, kernel-module) in `50-kastell-deep.rules` with immutability ordering
|
|
126
|
+
- **Lock: sysctl deep tuning** — 21 kernel hardening settings (dmesg_restrict, kptr_restrict, bpf_jit_harden, rp_filter, ASLR, core dumps)
|
|
127
|
+
- **Lock: pwquality** — CIS L1 password policy (minlen=14, complexity classes, maxrepeat=3), non-fatal with graceful skip
|
|
128
|
+
- **Lock: SSH cipher blacklist** — Weak ciphers/MACs/KEX removed via minus-prefix with `sshd -t` validation and automatic rollback
|
|
129
|
+
- **Lock: Docker runtime hardening** — daemon.json merge (no-new-privileges, live-restore, log rotation, icc:false) with platform-aware guards and reload-not-restart
|
|
130
|
+
- **Lock 19-step hardening** — Expanded from 16 to 19 steps (pwquality + SSH cipher + Docker hardening)
|
|
131
|
+
- **Audit 413 checks** — 4 new checks (KRN-BPF-JIT-HARDEN, LOG-AUDIT-TIME-RULES, LOG-AUDIT-NETWORK-RULES, LOG-AUDIT-MODULE-RULES)
|
|
132
|
+
|
|
133
|
+
### Fixed
|
|
134
|
+
- **jq injection prevention** — Docker hardening uses stdin pipe instead of shell interpolation
|
|
135
|
+
- **SSH sed tab pattern** — Cipher/MAC/KEX sed patterns now match both space and tab separators
|
|
136
|
+
- **Interactive menu** — Lock description updated from 16-step to 19-step
|
|
137
|
+
|
|
138
|
+
### Changed
|
|
139
|
+
- **WEAK_CIPHERS/MACS/KEX constants** — Single source in constants.ts, shared by lock and audit
|
|
140
|
+
- **Test coverage** — 4152→4156 tests (SSH cipher builder tests added)
|
|
141
|
+
|
|
142
|
+
## [1.11.0] - 2026-03-18
|
|
143
|
+
|
|
144
|
+
### Added
|
|
145
|
+
- **MCP tool descriptions** — Updated all 13 MCP tools with 27-category routing hints and accurate check counts
|
|
146
|
+
- **Audit display filter** — `audit --filter` for display-only category/severity filtering without re-running SSH
|
|
147
|
+
- **Audit fix score delta** — Post-fix score re-audit shows before/after comparison
|
|
148
|
+
- **Lock 16-step expansion** — `server lock` expanded from 5 to 16 hardening steps with grouped CLI output and dry-run preview
|
|
149
|
+
- **Lock step helpers** — `runLockStep` + 11 command builders for modular hardening (auditd, sysctl, pwquality, AIDE, etc.)
|
|
150
|
+
- **SSH host key remediation** — Proactive `removeStaleHostKey` before SSH polling + error output with remediation hints
|
|
151
|
+
|
|
152
|
+
### Fixed
|
|
153
|
+
- **Interactive menu audit filters** — Audit sub-menu now correctly passes filter and fix options
|
|
154
|
+
- **FW-05 passed field** — Fixed incorrect variable in firewall IPv6 check (`passed: isActive` → `passed: ipv6Enabled`)
|
|
155
|
+
- **MCP check count** — Corrected inflated 488+ count back to accurate 409
|
|
156
|
+
- **Audit filter+fix hardening** — Shell metacharacter guard, severity validation, structured error logging
|
|
157
|
+
- **CLOUDMETA_CATALOG_INPUT format** — Fixed cloud metadata catalog input format
|
|
158
|
+
- **SSH retry error handling** — Added `.catch()` to SSH retry preventing unhandled rejections
|
|
159
|
+
|
|
160
|
+
### Changed
|
|
161
|
+
- **`getErrorMessage` reuse** — Consolidated error message extraction across modules
|
|
162
|
+
- **`extractSentinelValue` scoping** — Documented as intentionally local to firewall.ts
|
|
163
|
+
|
|
164
|
+
## [1.10.1] - 2026-03-17
|
|
165
|
+
|
|
166
|
+
### Added
|
|
167
|
+
- **sshStream stdin support** — SSH batch commands piped via stdin for reliable cross-platform execution
|
|
168
|
+
- **Audit batch error reporting** — Structured error details when audit SSH batches fail
|
|
169
|
+
|
|
170
|
+
### Fixed
|
|
171
|
+
- **Windows SSH argument escaping** — Batch commands now use stdin pipe instead of spawn arguments, fixing truncation on Windows
|
|
172
|
+
- **Audit sentinel wrappers** — Added sentinel markers for 4 categories (accounts, services, boot, scheduling — 24 checks) fixing parser mismatches
|
|
173
|
+
- **Cloud-init SSH lockout** — Fixed DigitalOcean + Coolify SSH lockout caused by ssh.socket/needrestart/UFW ordering
|
|
174
|
+
- **Interactive menu back navigation** — Back option now works correctly in nested sub-menus
|
|
175
|
+
- **DEBIAN_FRONTEND=noninteractive** — Added to Coolify and Dokploy cloud-init scripts preventing apt prompts
|
|
176
|
+
- **Provision reliability** — Orphan cleanup, Vultr boot timeout (135s), SSH hardening safety guards
|
|
177
|
+
- **Snapshot Zod schema** — Added 6 P52 optional fields (vpsIrrelevant, connectionError, vpsType, vpsAdjustedCount, skippedCategories, warnings) preventing silent strip on load
|
|
178
|
+
|
|
179
|
+
## [1.10.0] - 2026-03-16
|
|
180
|
+
|
|
181
|
+
### Added
|
|
182
|
+
- **Audit Pro: 27 categories, 406+ checks** — Expanded from 9 categories / 46 checks to 27 categories / 406+ checks with Lynis-parity coverage
|
|
183
|
+
- **New audit categories** — Accounts, Services, Boot, Scheduling, Time, Banners, Crypto, File Integrity, Malware, MAC, Memory, Secrets, Cloud Metadata, Supply Chain, Backup Hygiene, Resource Limits, Incident Readiness, DNS Security
|
|
184
|
+
- **Compliance mapping** — CIS Ubuntu L1/L2 (290 mappings), PCI-DSS v4.0 (89 refs), HIPAA §164.312 (41 refs)
|
|
185
|
+
- **`audit --list-checks`** — Static catalog of all 406+ checks with severity, description, and compliance refs
|
|
186
|
+
- **`audit --profile`** — Filter audit by compliance profile (cis-level1, cis-level2, pci-dss, hipaa)
|
|
187
|
+
- **`audit --compliance`** — Framework-grouped compliance report (cis, pci-dss, hipaa)
|
|
188
|
+
- **VPS detection** — Auto-detect virtualization type (kvm, vmware, xen, etc.) with VPS-irrelevant check skipping
|
|
189
|
+
- **Interactive menu v1.10 options** — Audit sub-menu now includes list-checks, profile filter, compliance report; notify sub-menu includes list/remove
|
|
190
|
+
|
|
191
|
+
### Changed
|
|
192
|
+
- **Weighted category scoring** — Categories now have configurable weights (Secrets, Supply Chain weight=3)
|
|
193
|
+
- **Snapshot schema v2** — Added `auditVersion` field, automatic v1→v2 migration, Zod strict validation
|
|
194
|
+
- **Version-aware trend detection** — Methodology-change banner when comparing different audit versions
|
|
195
|
+
- **Semantic check IDs** — All checks renamed from numeric to `CATEGORY-DESCRIPTION` format (e.g., `SSH-PASSWORD-AUTH`)
|
|
196
|
+
- **Named separators + 3-tier batches** — SSH command grouping optimized for audit performance
|
|
197
|
+
- **Terminal formatter** — Category grouping (fail expanded / pass collapsed), stats header, VPS banner
|
|
198
|
+
- **QuickWins** — Max 7, compliance boost factor 1.5x for compliance-mapped checks
|
|
199
|
+
- **Provider boot timeout** — Provider-specific polling: Hetzner 30s, DigitalOcean 60s, Vultr 135s, Linode 120s
|
|
200
|
+
- Test count: 3,333 → 3,992 (+659 new tests across 178 suites)
|
|
201
|
+
|
|
202
|
+
### Fixed
|
|
203
|
+
- **Pre-release audit cleanup** — Deduplicated formatter helpers, strengthened secrets regex, fixed compliance mapper edge cases, added NaN guards
|
|
204
|
+
- **Boot timeout** — Vultr/Linode provision no longer times out due to fixed 30s polling
|
|
205
|
+
|
|
206
|
+
## [1.9.1] - 2026-03-15
|
|
207
|
+
|
|
208
|
+
### Security
|
|
209
|
+
- **Socket.dev alert fixes** — Resolved 3 supply-chain alerts on npm:
|
|
210
|
+
- `curl|bash` update commands moved from `constants.ts` into adapter files (eliminates obfuscated code alert)
|
|
211
|
+
- `child_process` import removed from `deploy.ts` — uses `removeStaleHostKey()` utility instead
|
|
212
|
+
- `globalThis["fetch"]` false positive documented in SOCKET_JUSTIFICATION.md
|
|
213
|
+
|
|
214
|
+
## [1.9.0] - 2026-03-15
|
|
215
|
+
|
|
216
|
+
### Fixed
|
|
217
|
+
- **doctor --fix apt hang** — `DEBIAN_FRONTEND=noninteractive` prefix added to apt fix commands over SSH, preventing interactive prompts on headless servers
|
|
218
|
+
- **restore --force bypass** — `--force` flag now auto-selects the latest backup without prompting when `--backup` is not specified
|
|
219
|
+
- **README codecov badge** — Replaced broken codecov.io badge URL with shields.io integration for reliable rendering with logo
|
|
220
|
+
|
|
221
|
+
### Security
|
|
222
|
+
- **Notify token keychain migration** — Notification tokens (Telegram/Discord/Slack) moved from plain-text config to OS keychain storage with secure file-backed fallback for headless environments
|
|
223
|
+
- **SSH command builder** — New `SshCommand` branded type with `cmd()`/`raw()` builders and POSIX `shellEscape()` — eliminates string concatenation injection risk across 11 core modules
|
|
224
|
+
|
|
225
|
+
### Changed
|
|
226
|
+
- **MCP SDK isolation** — Dynamic `import()` boundary ensures non-MCP commands (`status`, `fleet`, `audit`, etc.) never load MCP SDK's 179 transitive dependencies
|
|
227
|
+
- **execSync → spawnSync migration** — Shell invocation eliminated from `ssh.ts` and `doctor.ts`, closing Socket.dev shell alert
|
|
228
|
+
- **MCP handler decomposition** — `serverSecure` (10 handlers) and `serverBackup` (6 handlers) extracted to colocated handler modules with 63 new unit tests
|
|
229
|
+
- **Quality audit fixes** — 16 code quality findings resolved: layer violations, duplication, naming consistency, constant extraction
|
|
230
|
+
- Test count: 3,175 → 3,333 (+158 new tests)
|
|
231
|
+
|
|
232
|
+
## [1.8.1] - 2026-03-15
|
|
233
|
+
|
|
234
|
+
### Added
|
|
235
|
+
- **Interactive menu complete** — All missing commands added to interactive menu: fleet, audit, lock, evidence, guard, doctor, backup-list, notify, completions with sub-prompts and emoji categories
|
|
236
|
+
- **`--force` flag** — Added to 7 CLI commands (backup, secure, lock, domain, update, maintain, evidence) for non-interactive/CI usage
|
|
237
|
+
- **`backup list` CLI command** — List all local backups (previously MCP-only)
|
|
238
|
+
- **Dokploy domain support** — CLI domain commands (add, remove, list, info) now work with Dokploy servers
|
|
239
|
+
- **`platformDefaults()` helper** — Eliminates repeated platform ternaries in domain/restart commands
|
|
240
|
+
- **Domain completions** — Added `list` and `info` to domain subcommands in bash/zsh/fish
|
|
241
|
+
|
|
242
|
+
### Fixed
|
|
243
|
+
- **Dokploy backup/restore** — Fixed `-U postgres` → `-U dokploy` (role "postgres" does not exist)
|
|
244
|
+
- **Restart message** — Now shows correct platform name and port (Dokploy:3000 vs Coolify:8000)
|
|
245
|
+
- **MCP mode detection** — `resolvePlatform()` used in MCP serverInfo (mode now correctly shows "dokploy")
|
|
246
|
+
- **MCP serverManage** — Added "dokploy" to mode enum
|
|
247
|
+
|
|
248
|
+
### Changed
|
|
249
|
+
- Interactive doctor prompt: `--check-tokens` → `--fresh`
|
|
250
|
+
- Interactive backup prompt: confirm dialog → sub-menu (create/all)
|
|
251
|
+
- MCP version metadata added to all tool responses
|
|
252
|
+
|
|
253
|
+
## [1.8.0] - 2026-03-15
|
|
254
|
+
|
|
255
|
+
### Added
|
|
256
|
+
- **Fleet Visibility** (`kastell fleet`) — Parallel health check across all servers with status table (online/degraded/offline), audit scores, response times. `--json` for structured output
|
|
257
|
+
- **Notification Module** (`kastell notify`) — Multi-channel alert dispatch: webhook, Slack, Discord, email (SMTP). `kastell notify add-channel` + `kastell notify test`
|
|
258
|
+
- **Guard Notification Integration** — Guard breach alerts automatically dispatched via configured notification channels with severity categorization
|
|
259
|
+
- **Doctor --fix** (`kastell doctor --fix`) — Interactive auto-remediation for doctor findings. Per-finding confirm gate, `--force` to skip prompts, `--dry-run` to preview. Whitelisted fix commands only
|
|
260
|
+
- **MCP server_fleet tool** — Fleet visibility exposed via MCP (list all servers with health/audit status)
|
|
261
|
+
- **Shell completions updated** — fleet, notify, audit, evidence commands and all v1.8 flags added to bash/zsh/fish generators
|
|
262
|
+
|
|
263
|
+
### Security
|
|
264
|
+
- **OWASP review** — 8 security fixes: evidence path traversal (H-01), evidence lines sanitize (H-02), webhook SSRF protection (M-01), guard stale comment fix (M-03), doctor fix whitelist (M-04), metrics file permission (L-03), audit history file permission (L-04), backup restore safe mode guard (I-01)
|
|
265
|
+
- 8 code quality improvements: notify DRY (sendHttp), Promise.all optimization, channel validation, guard version tracking, firewall platform messages, secure score DRY, default audit constants, IP validation consolidation
|
|
266
|
+
|
|
267
|
+
### Changed
|
|
268
|
+
- **Architecture**: Layer violation fix — `firewallSetup` and `secureSetup` moved from `commands/` to `core/`
|
|
269
|
+
- **Architecture**: Adapter deduplication — `sharedCreateBackup` and `sharedRestoreBackup` extracted to `src/adapters/shared.ts`
|
|
270
|
+
- **Architecture**: PostSetup decomposed into `barePostSetup` + `platformPostSetup`
|
|
271
|
+
- Platform name capitalized in restore backup step labels (e.g., "coolify" → "Coolify")
|
|
272
|
+
- Removed `.planning/` from git tracking (was leaking internal planning files)
|
|
273
|
+
- Test count: 3,038 → 3,175 (+137 new tests)
|
|
274
|
+
- MCP tools: 12 → 13 (server_fleet added)
|
|
275
|
+
|
|
276
|
+
## [1.7.0] - 2026-03-14
|
|
277
|
+
|
|
278
|
+
### Added
|
|
279
|
+
- **Server Lock** (`kastell lock`) — One-command production hardening: SSH key-only auth, fail2ban, UFW firewall, sysctl hardening, unattended-upgrades. Shows audit score before/after. `--dry-run` preview, `--force` for already-hardened servers
|
|
280
|
+
- **Backup Schedule** (`kastell backup --schedule`) — Cron-based automatic backups via SSH crontab. Supports `--schedule hourly|daily|weekly|custom` with custom cron expressions
|
|
281
|
+
- **Guard Daemon** (`kastell guard start|stop|status`) — Autonomous security monitoring via remote cron. Checks disk/RAM/CPU/audit every 5 minutes with threshold breach detection
|
|
282
|
+
- **Risk Trend** (`kastell audit --trend`) — Audit score trend analysis over time. `--days N` to control window. Terminal and JSON output formats
|
|
283
|
+
- **Doctor (Server Mode)** (`kastell doctor <server>`) — Per-server proactive health analysis: disk trending, high swap, stale packages, fail2ban bans, audit regression, old backups, reclaimable Docker space. `--fresh` for live SSH data, `--json` for structured output
|
|
284
|
+
- **3 new MCP tools**: `server_guard` (start/stop/status), `server_doctor` (summary/json), `server_lock` (dry-run/production/force)
|
|
285
|
+
- **Shell completions**: guard, lock, doctor flags added for bash/zsh/fish
|
|
286
|
+
|
|
287
|
+
### Security
|
|
288
|
+
- **OWASP review**: 10 security and quality fixes — sanitized error paths, hardened input validation, tightened type guards
|
|
289
|
+
- **Dependency fix**: flatted 3.3.3 → 3.4.1 (unbounded recursion DoS)
|
|
290
|
+
|
|
291
|
+
### Fixed
|
|
292
|
+
- CLI `list`/`status` now shows actual platform label (dokploy/coolify/bare) instead of generic "mode"
|
|
293
|
+
- `--force` flag added to secure/update CLI commands
|
|
294
|
+
- MCP evidence `force` parameter passthrough
|
|
295
|
+
|
|
296
|
+
### Changed
|
|
297
|
+
- Test count: 2,467 → 3,038 (+571 new tests)
|
|
298
|
+
- MCP tools: 9 → 12 (server_guard, server_doctor, server_lock added)
|
|
299
|
+
|
|
300
|
+
## [1.6.0] - 2026-03-11
|
|
301
|
+
|
|
302
|
+
### Added
|
|
303
|
+
- **Audit Snapshots** (`kastell audit --snapshot`) — Persist audit results as timestamped JSON snapshots. `--snapshots` to list saved snapshots
|
|
304
|
+
- **Audit Diff** (`kastell audit --diff <id>`, `--compare <id1> <id2>`) — Compare audit results between snapshots. Shows category-level score changes and new/fixed findings
|
|
305
|
+
- **Evidence Collection** (`kastell evidence <server>`) — Forensic evidence package: firewall rules, auth.log, listening ports, system logs, Docker info. SHA256 checksums per file. Written to `~/.kastell/evidence/{server}/{date}/`
|
|
306
|
+
- **MCP server_evidence tool** — Evidence collection exposed via MCP
|
|
307
|
+
- **Adapter contract conformance tests** — Verify PlatformAdapter interface compliance
|
|
308
|
+
- **Infrastructure utilities**: `withRetry` (exponential backoff for provider API calls), `withFileLock` (file-based mutex for config writes)
|
|
309
|
+
- **Provider retry integration** — All provider GET methods wrapped with `withRetry`
|
|
310
|
+
- **Config lock integration** — All config writes protected with `withFileLock`
|
|
311
|
+
- **Mode migration** — Automatic `ServerMode` field addition to legacy server records
|
|
312
|
+
|
|
313
|
+
### Security
|
|
314
|
+
- Consolidated IP validation, removed dead code, hardened security paths
|
|
315
|
+
- Auth keyring: replaced top-level await with lazy require (fixes non-interactive environments)
|
|
316
|
+
|
|
317
|
+
### Fixed
|
|
318
|
+
- Evidence dynamic section-to-filename mapping prevents index mismatch bug
|
|
319
|
+
- Linode test mocks updated to use Error instances for `withProviderErrorHandling`
|
|
320
|
+
|
|
321
|
+
### Changed
|
|
322
|
+
- Deduplicated provider error handling into `withProviderErrorHandling` + `extractApiMessage`
|
|
323
|
+
- Test count: 2,266 → 2,467 (+201 new tests)
|
|
324
|
+
- MCP tools: 8 → 9 (server_evidence added)
|
|
325
|
+
|
|
326
|
+
## [1.5.2] - 2026-03-09
|
|
327
|
+
|
|
328
|
+
### Fixed
|
|
329
|
+
- **Phase 2 code review**: 30 bug fixes across critical, high, medium, and low severity (3C+8H+14M+5L) — provider validation, error handling, type safety improvements
|
|
330
|
+
- **Phase 1 remaining fixes**: 15 files — provider validation hardening, audit check corrections, backup safety guards
|
|
331
|
+
|
|
332
|
+
### Changed
|
|
333
|
+
- **CI**: Automatic GitHub Release workflow on tag push
|
|
334
|
+
- **Docs (TR)**: Security audit section, MCP server_audit, CI pipeline example added to Turkish README
|
|
335
|
+
|
|
336
|
+
## [1.5.1] - 2026-03-08
|
|
337
|
+
|
|
338
|
+
### Fixed
|
|
339
|
+
- **Dokploy update command**: Install script now called with `update` argument — previously ran fresh-install mode which failed on port 80/443 conflict with running Dokploy instance
|
|
340
|
+
- 5 Dokploy integration bugs found during real-server testing (health check port, firewall ports, backup paths, restore commands, version detection)
|
|
341
|
+
|
|
342
|
+
## [1.5.0] - 2026-03-08
|
|
343
|
+
|
|
344
|
+
### Added
|
|
345
|
+
- **Security audit system**: `kastell audit` command with 9 check categories (SSH, auth, firewall, Docker, kernel, filesystem, network, logging, updates), scoring 0-100, terminal/JSON/summary/badge formatters
|
|
346
|
+
- **Audit history**: `kastell audit --history` tracks score trends over time with comparison
|
|
347
|
+
- **Audit watch mode**: `kastell audit --watch` monitors security score changes on interval
|
|
348
|
+
- **Audit quick wins**: `kastell audit --quick-wins` suggests highest-impact fixes
|
|
349
|
+
- **Audit auto-fix**: `kastell audit --fix` applies safe remediations automatically
|
|
350
|
+
- **MCP server_audit tool**: Full audit capabilities exposed via MCP (summary/json/score formats)
|
|
351
|
+
- **Token buffer**: In-memory token protection with controlled exposure window
|
|
352
|
+
- **Platform auto-detection**: SSH-based `detectPlatform()` checks filesystem markers for Dokploy/Coolify/bare
|
|
353
|
+
|
|
354
|
+
### Changed
|
|
355
|
+
- Test count: 2,266 → 2,467 (+201 new tests)
|
|
356
|
+
- Test suites: 86 → 112 (+26 new suites)
|
|
357
|
+
- MCP tools: 7 → 8 (server_audit added)
|
|
358
|
+
|
|
359
|
+
## [1.4.0] - 2026-03-08
|
|
360
|
+
|
|
361
|
+
### Added
|
|
362
|
+
- **CLI header**: Gradient ASCII banner with cyan-to-blue color scheme, version info bar, and quick-start command examples on interactive mode launch
|
|
363
|
+
- **Shell completions**: `kastell completions bash|zsh|fish` generates shell completion scripts for tab-completion
|
|
364
|
+
- **Config validation**: `kastell config validate` checks `servers.yaml` for structural and type errors using Zod strict schemas
|
|
365
|
+
- **Version check**: `kastell --version` now notifies if a newer version is available on npm
|
|
366
|
+
- **Dry-run support**: Added `--dry-run` flag to `destroy`, `remove`, `backup`, `snapshot`, and `secure` commands
|
|
367
|
+
- **Dokploy lifecycle**: Full Dokploy adapter with update, maintain, logs, health, backup, and restore support
|
|
368
|
+
- **Platform adapters**: `src/adapters/` architecture — Coolify and Dokploy adapters implement `PlatformAdapter` interface
|
|
369
|
+
|
|
370
|
+
### Changed
|
|
371
|
+
- Interactive menu no longer uses figlet — replaced with custom gradient ASCII art header
|
|
372
|
+
- `PROVIDER_REGISTRY` centralized in `src/constants.ts` as single source of truth
|
|
373
|
+
- Test count: 2,099 → 2,266 (+167 new tests)
|
|
374
|
+
- Test suites: 78 → 86 (+8 new suites)
|
|
375
|
+
|
|
376
|
+
## [1.3.1] - 2026-03-05
|
|
377
|
+
|
|
378
|
+
### Changed
|
|
379
|
+
- **Metadata update**: Package description, keywords, and homepage updated for Kastell branding
|
|
380
|
+
- **Repository references**: All internal references updated from `omrfc/kastell` to `kastelldev/kastell`
|
|
381
|
+
|
|
382
|
+
## [1.3.0] - 2026-03-05
|
|
383
|
+
|
|
384
|
+
### Breaking Changes
|
|
385
|
+
- **Package renamed**: `quicklify` is now `kastell` on npm. Install with `npm install -g kastell`
|
|
386
|
+
- **Binary renamed**: `quicklify` CLI is now `kastell`, `quicklify-mcp` is now `kastell-mcp`
|
|
387
|
+
- **License changed**: MIT -> Apache License 2.0 (patent protection added)
|
|
388
|
+
|
|
389
|
+
### Added
|
|
390
|
+
- **Config migration**: Automatic migration from `~/.quicklify` to `~/.kastell` on first run (copies entire directory, `.migrated` flag prevents re-migration)
|
|
391
|
+
- **NOTICE file**: Apache 2.0 attribution notice added
|
|
392
|
+
|
|
393
|
+
### Changed
|
|
394
|
+
- **Package identity**: name `kastell`, version `1.3.0`, homepage `https://kastell.dev`
|
|
395
|
+
- **Environment variable**: `KASTELL_SAFE_MODE` is now the primary env var for MCP safe mode. `QUICKLIFY_SAFE_MODE` still works with a one-time deprecation warning (backward compat until v2.0)
|
|
396
|
+
- **Internal types**: `QuicklifyYamlConfig` -> `KastellYamlConfig`, `QuicklifyConfig` -> `KastellConfig`, `QuicklifyResult` -> `KastellResult`
|
|
397
|
+
- **Config directory**: `~/.quicklify/` -> `~/.kastell/` (automatic migration on first run)
|
|
398
|
+
- **SSH key prefix**: `quicklify-` -> `kastell-` for auto-generated SSH keys
|
|
399
|
+
- **Snapshot prefix**: `quicklify-` -> `kastell-` for new snapshots (existing `quicklify-*` snapshots still recognized via dual-prefix filter)
|
|
400
|
+
- **Export filename**: Default export changed from `quicklify-export.json` to `kastell-export.json`
|
|
401
|
+
- **Update check**: Now queries `registry.npmjs.org/kastell/latest`
|
|
402
|
+
- **All documentation**: README.md, README.tr.md, SECURITY.md, CONTRIBUTING.md, llms.txt updated to Kastell branding
|
|
403
|
+
- **Example config**: `quicklify.yml` renamed to `kastell.yml`
|
|
404
|
+
- **MCP config**: Server name changed from `quicklify` to `kastell`
|
|
405
|
+
|
|
406
|
+
### Deprecated
|
|
407
|
+
- `quicklify` npm package (will show deprecation notice pointing to `kastell`)
|
|
408
|
+
- `QUICKLIFY_SAFE_MODE` env var (use `KASTELL_SAFE_MODE` instead, removed in v2.0)
|
|
409
|
+
|
|
410
|
+
## [1.2.1] - 2026-03-02
|
|
411
|
+
|
|
412
|
+
### Security
|
|
413
|
+
- **CRITICAL FIX**: `stripSensitiveData()` now sanitizes `error.response.data` and `error.response.headers` — prevents API tokens, rootPass, and other sensitive data from leaking via error cause chains
|
|
414
|
+
- Whitelist-based `sanitizeResponseData()` preserves only known error message fields (Hetzner `error.message`, DigitalOcean `message`, Vultr `error`, Linode `errors[].reason`)
|
|
415
|
+
- Response headers cleared to prevent `set-cookie` and tracking header exposure
|
|
416
|
+
- Linode `root_pass` reflection in error responses now stripped
|
|
417
|
+
|
|
418
|
+
### Changed
|
|
419
|
+
- **Refactoring**: Extracted `init.ts` command logic into `src/core/deploy.ts` (619 → 243 lines)
|
|
420
|
+
- **Refactoring**: `PROVIDER_REGISTRY` centralized in `src/constants.ts` — single source of truth for provider metadata
|
|
421
|
+
- **Refactoring**: `stripSensitiveData()` consolidated from 4 provider files into `src/providers/base.ts`
|
|
422
|
+
- **Security**: SCP path hardening via `assertSafePath()` with shell metacharacter rejection
|
|
423
|
+
- **Security**: Token sanitization via `sanitizedEnv()` applied to all remaining child process calls
|
|
424
|
+
- Test count: 2,047 → 2,099 (+52 new tests)
|
|
425
|
+
- Test suites: 76 → 78 (+2 new suites)
|
|
426
|
+
|
|
427
|
+
## [1.2.0] - 2026-03-01
|
|
428
|
+
|
|
429
|
+
### Added
|
|
430
|
+
- **Bare Mode** — Generic VPS support without Coolify (`--mode bare` on init/add)
|
|
431
|
+
- `ServerRecord.mode` field: `"coolify"` (default) or `"bare"`
|
|
432
|
+
- `requireCoolifyMode()` guard blocks Coolify-only operations on bare servers
|
|
433
|
+
- `getBareCloudInit()` — hardening-only cloud-init script (UFW + system updates)
|
|
434
|
+
- Bare mode support across all 23 CLI commands and 7 MCP tools
|
|
435
|
+
- 2GB RAM minimum removed for bare mode provisioning
|
|
436
|
+
- Backward compatibility: legacy records without `mode` field default to `"coolify"`
|
|
437
|
+
- **Interactive Menu** — Run `quicklify` without arguments for a categorized menu
|
|
438
|
+
- 6 categories: Server Management, Security, Monitoring & Logs, Backup & Snapshots, Maintenance, Configuration
|
|
439
|
+
- Sub-option prompts for each action (mode, template, log source, port, etc.)
|
|
440
|
+
- `← Back` navigation to return to main menu at any point
|
|
441
|
+
- 49 new tests (`interactive.test.ts`)
|
|
442
|
+
- **MCP `sizes` action** — `server_info` tool now supports listing available server types with prices per provider/region
|
|
443
|
+
- **MCP shared utilities** — `src/mcp/utils.ts` with `resolveServerForMcp`, `mcpSuccess`, `mcpError`
|
|
444
|
+
- **SSH host key auto-fix** — `removeStaleHostKey()` helper auto-removes stale known_hosts entries
|
|
445
|
+
- Health command detects host key mismatch and suggests fix
|
|
446
|
+
- SSH retry mechanism after stale key removal
|
|
447
|
+
- **UX improvements** (6 enhancements):
|
|
448
|
+
- Better dpkg lock messaging during provisioning
|
|
449
|
+
- Token source display (env var vs prompt)
|
|
450
|
+
- Firewall status shows current rules inline
|
|
451
|
+
- Domain info shows current FQDN
|
|
452
|
+
- Orphan backup cleanup
|
|
453
|
+
- Backup/restore shows provider + IP context
|
|
454
|
+
|
|
455
|
+
### Security
|
|
456
|
+
- **OWASP hardening**: `assertSafePath()` for SCP paths (shell metacharacter check including `<>`)
|
|
457
|
+
- **Port validation**: MCP port range restricted to 1-65535
|
|
458
|
+
- **Token isolation**: `sanitizedEnv()` applied to all `spawn`/`exec`/`spawnSync` calls including `openBrowser`, `sshKey`, and `removeStaleHostKey`
|
|
459
|
+
- **SECURITY.md**: Added OWASP Top 10 compliance table with detailed mitigation descriptions
|
|
460
|
+
|
|
461
|
+
### Fixed
|
|
462
|
+
- Init `--full-setup` crash on bare mode servers
|
|
463
|
+
- Domain `--name` flag ignored on bare mode
|
|
464
|
+
- Cloud-init completion wait missing
|
|
465
|
+
- Bare mode showing incorrect port information
|
|
466
|
+
- Health command missing query argument
|
|
467
|
+
- Restart bare mode "command not found" message
|
|
468
|
+
- MCP SSH path incorrect during provision
|
|
469
|
+
|
|
470
|
+
### Changed
|
|
471
|
+
- Test count: 1,758 → 2,047 (+289 new tests)
|
|
472
|
+
- Test suites: 64 → 76 (+12 new suites)
|
|
473
|
+
- Banner slogan updated to "Self-hosting, fully managed"
|
|
474
|
+
- README interactive menu documentation with example output
|
|
475
|
+
- LICENSE name correction: "omrfc" → "Ömer Faruk CAN"
|
|
476
|
+
- `.gitignore`: added `servers.json`
|
|
477
|
+
|
|
478
|
+
## [1.1.0] - 2026-02-27
|
|
479
|
+
|
|
480
|
+
### Added
|
|
481
|
+
- **MCP Server** — Built-in Model Context Protocol server for AI-powered server management with 7 tools:
|
|
482
|
+
- `server_info` — `list`, `status`, `health` (readOnly)
|
|
483
|
+
- `server_logs` — `logs`, `monitor` (readOnly)
|
|
484
|
+
- `server_manage` — `add`, `remove`, `destroy` (destructive, SAFE_MODE on destroy)
|
|
485
|
+
- `server_maintain` — `update`, `restart`, `maintain`
|
|
486
|
+
- `server_secure` — `secure-setup`, `secure-audit`, `firewall-setup`, `firewall-add`, `firewall-remove`, `firewall-status`, `domain-set`, `domain-remove`, `domain-check`, `domain-info`
|
|
487
|
+
- `server_backup` — `backup-create`, `backup-list`, `backup-restore`, `snapshot-create`, `snapshot-list`, `snapshot-delete` (SAFE_MODE on restore/delete)
|
|
488
|
+
- `server_provision` — `create` (destructive, SAFE_MODE — creates billable cloud resources)
|
|
489
|
+
- Structured JSON responses with `suggested_actions` for AI context optimization
|
|
490
|
+
- Tool annotations: `readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`
|
|
491
|
+
- Rate limiting guidance in tool descriptions
|
|
492
|
+
- SAFE_MODE guards on destructive operations (provision, destroy, restore, snapshot-delete)
|
|
493
|
+
- **`src/core/` module** — Pure business logic extracted from CLI commands (no CLI dependencies)
|
|
494
|
+
- `status.ts` — `checkCoolifyHealth`, `getCloudServerStatus`, `checkServerStatus`, `checkAllServersStatus`
|
|
495
|
+
- `tokens.ts` — `getProviderToken`, `collectProviderTokensFromEnv` (non-interactive token resolution)
|
|
496
|
+
- `secure.ts` — SSH hardening + audit (pure functions + async wrappers)
|
|
497
|
+
- `firewall.ts` — UFW management (pure functions + async wrappers)
|
|
498
|
+
- `domain.ts` — FQDN/DNS management (pure functions + async wrappers)
|
|
499
|
+
- `backup.ts` — Backup/restore (20 pure functions + SCP helpers)
|
|
500
|
+
- `snapshot.ts` — Snapshot create/list/delete + cost estimate
|
|
501
|
+
- `provision.ts` — Server provisioning (13-step flow: validate → token → SSH → cloudInit → create → boot → IP → save)
|
|
502
|
+
- **`src/mcp/` module** — MCP server implementation
|
|
503
|
+
- `src/mcp/server.ts` — MCP server setup with 7 tool registrations
|
|
504
|
+
- `src/mcp/tools/` — 7 tool handlers (serverInfo, serverLogs, serverManage, serverMaintain, serverSecure, serverBackup, serverProvision)
|
|
505
|
+
- `src/mcp/index.ts` — stdio transport entry point
|
|
506
|
+
- `bin/quicklify-mcp` — MCP server binary entry point
|
|
507
|
+
- SSRF defense: `assertValidIp()` added to `checkCoolifyHealth` (IP format validation before HTTP request)
|
|
508
|
+
- Stack trace sanitization in MCP error responses via `getErrorMessage()`
|
|
509
|
+
|
|
510
|
+
### Security
|
|
511
|
+
- **Path traversal protection**: `backupId` validated with Zod regex (`/^[\w-]+$/`) + `path.resolve()` guard in restore
|
|
512
|
+
- **SAFE_MODE enforcement**: Added `isSafeMode()` guards on `restart`, `maintain`, and `snapshot-create` MCP actions
|
|
513
|
+
- **IP validation hardened**: `assertValidIp()` now validates octet range (0-255), IP removed from error messages
|
|
514
|
+
- **stderr sanitization**: New `sanitizeStderr()` function redacts IPs, home paths, tokens, secrets (200 char limit) — applied to all backup/restore/logs error output
|
|
515
|
+
- **Port validation**: MCP `server_secure` port restricted to `z.number().min(1).max(65535)`
|
|
516
|
+
- **Provider enum validation**: MCP `server_manage` provider changed from `z.string()` to `z.enum()` (prevents invalid provider injection)
|
|
517
|
+
- **Manifest hardening**: `serverIp` field removed from `BackupManifest` type, manifest files written with `mode: 0o600`
|
|
518
|
+
- **SCP IP validation**: `assertValidIp()` added to `scpDownload()` and `scpUpload()` before spawning child process
|
|
519
|
+
- **Log redaction**: `manage.ts` stderr no longer exposes server IP address
|
|
520
|
+
- **SSH key auto-generation**: `provision` now auto-generates SSH key when none exists (instead of skipping)
|
|
521
|
+
- `.mcp.json` added to `.gitignore` (contains local absolute paths)
|
|
522
|
+
|
|
523
|
+
### Changed
|
|
524
|
+
- `src/commands/status.ts` refactored to use `src/core/status.ts` (DRY: eliminated duplicate Coolify health check)
|
|
525
|
+
- Test count: 1369 → 1758 (+389 new tests across 9 new test suites)
|
|
526
|
+
- Test suites: 55 → 64
|
|
527
|
+
|
|
528
|
+
### Dependencies
|
|
529
|
+
- Added `@modelcontextprotocol/sdk` ^1.27.1 (MCP server SDK)
|
|
530
|
+
- Added `zod` ^4.3.6 (MCP input schema validation)
|
|
531
|
+
|
|
532
|
+
## [1.0.5] - 2026-02-26
|
|
533
|
+
|
|
534
|
+
### Added
|
|
535
|
+
- `mapSshError` — 10 SSH error patterns mapped to actionable hints (connection refused, permission denied, host key, timeout, reset, hostname, command not found, disk full, broken pipe)
|
|
536
|
+
- `mapFileSystemError` — 4 filesystem error codes mapped to hints (ENOENT, EACCES, EPERM, ENOSPC)
|
|
537
|
+
- `getErrorMessage` — DRY helper replacing `error instanceof Error ? error.message : String(error)` across 15 command files
|
|
538
|
+
|
|
539
|
+
### Changed
|
|
540
|
+
- All 53 catch blocks now use appropriate error mappers: Provider API → `mapProviderError`, SSH → `mapSshError`, Filesystem → `mapFileSystemError`
|
|
541
|
+
- `mapProviderError` spread to 5 additional files (restart, maintain, status, update, snapshot)
|
|
542
|
+
- 3 silent catches in backup.ts now log error messages and provide SSH hints
|
|
543
|
+
- Test count: 1334 → 1369 (+35 new error hint integration tests)
|
|
544
|
+
|
|
545
|
+
## [1.0.4] - 2026-02-25
|
|
546
|
+
|
|
547
|
+
### Security
|
|
548
|
+
- Restore rollback: automatically restart Coolify if restore steps 3-5 fail after Coolify was stopped
|
|
549
|
+
- Fail2ban warning: show "partially complete" instead of misleading "complete" when fail2ban fails
|
|
550
|
+
- SSH key warnings: stronger guidance to run `quicklify secure setup` when key generation/upload fails
|
|
551
|
+
|
|
552
|
+
## [1.0.3] - 2026-02-25
|
|
553
|
+
|
|
554
|
+
### Added
|
|
555
|
+
- `doctor --check-tokens` — Validate provider API tokens from environment variables against live APIs (Hetzner, DigitalOcean, Vultr, Linode)
|
|
556
|
+
- Update notification — Check npm registry for newer versions (24h cache, non-blocking)
|
|
557
|
+
- Auto-open browser — Automatically open Coolify dashboard after successful `init` deployment (platform-aware, `--no-open` to disable)
|
|
558
|
+
- Error mapper — Actionable error messages with provider-specific URLs for billing, token management, and troubleshooting
|
|
559
|
+
|
|
560
|
+
### Changed
|
|
561
|
+
- Init onboarding — Improved post-deployment "What's Next?" guide with numbered steps and copy-paste commands
|
|
562
|
+
- README slogan updated to "Self-hosting made simple" (platform-agnostic)
|
|
563
|
+
- CONTRIBUTING.md completely rewritten to reflect current project state (22 commands, 5 providers, 13 utils)
|
|
564
|
+
|
|
565
|
+
### Documentation
|
|
566
|
+
- `llms.txt` — AI-friendly project documentation with architecture, commands, and workflows
|
|
567
|
+
|
|
568
|
+
## [1.0.2] - 2026-02-24
|
|
569
|
+
|
|
570
|
+
### Security
|
|
571
|
+
- Sanitize error cause chains to prevent API token leakage in all provider errors
|
|
572
|
+
- Mask process title when `--token` flag is used
|
|
573
|
+
- Replace `execSync` with `spawnSync` for ssh-keygen (prevent shell injection)
|
|
574
|
+
- Add shell-safe assertions to domain FQDN and DNS check commands
|
|
575
|
+
- Case-insensitive + nested security key detection in YAML config
|
|
576
|
+
- Strip unknown fields from imported server data
|
|
577
|
+
- Add IP address format validation to all SSH functions
|
|
578
|
+
- Filter sensitive environment variables from child processes
|
|
579
|
+
- Add `StrictHostKeyChecking` to interactive SSH connections
|
|
580
|
+
- Set file permissions (`0o600`) on export files
|
|
581
|
+
- Set directory permissions (`0o700`) on backup directories
|
|
582
|
+
- Add Vultr and Linode to default provider validation
|
|
583
|
+
- Clear `error.config.data` on Linode API failures (rootPass protection)
|
|
584
|
+
|
|
585
|
+
## [1.0.1] - 2026-02-24
|
|
586
|
+
|
|
587
|
+
### Added
|
|
588
|
+
- `quicklify snapshot create/list/delete` — VPS snapshot management with cost estimates
|
|
589
|
+
- Maintain integration: automatic snapshot offer before maintenance (with cost estimate)
|
|
590
|
+
- `sshKey.test.ts` — dedicated tests for SSH key utilities (13 tests)
|
|
591
|
+
- Provider snapshot support for Hetzner, DigitalOcean, Vultr, and Linode
|
|
592
|
+
|
|
593
|
+
### Fixed
|
|
594
|
+
- **domain.ts**: SQL escape for FQDN values (defense-in-depth against SQL injection)
|
|
595
|
+
- **restore.ts**: Path traversal protection with `basename()` for `--backup` flag
|
|
596
|
+
- **yamlConfig.ts**: Expanded security key detection (6 → 21 patterns including password, credential, jwt, bearer, etc.)
|
|
597
|
+
|
|
598
|
+
## [1.0.0] - 2026-02-23
|
|
599
|
+
|
|
600
|
+
### Added
|
|
601
|
+
- **Vultr provider** (`src/providers/vultr.ts`) - Full Vultr API v2 integration
|
|
602
|
+
- Base64-encoded user_data for cloud-init
|
|
603
|
+
- SSH key upload with HTTP 409 conflict handling
|
|
604
|
+
- OS: Ubuntu 24.04 (os_id: 2284)
|
|
605
|
+
- Power status normalization (running/stopped)
|
|
606
|
+
- **Linode (Akamai) provider** (`src/providers/linode.ts`) - Full Linode API v4 integration
|
|
607
|
+
- Auto-generated root_pass via `crypto.randomBytes()`
|
|
608
|
+
- SSH key upload via `/profile/sshkeys`
|
|
609
|
+
- Metadata user_data for cloud-init (base64)
|
|
610
|
+
- Disk size conversion (MB → GB)
|
|
611
|
+
- **`quicklify add`** command - Register existing Coolify servers to Quicklify management
|
|
612
|
+
- Interactive flow: provider → token → IP → verify Coolify → save
|
|
613
|
+
- Non-interactive: `--provider`, `--ip`, `--name`, `--skip-verify` flags
|
|
614
|
+
- Coolify verification via SSH (health check or `docker ps`)
|
|
615
|
+
- Duplicate detection by IP address
|
|
616
|
+
- **`quicklify maintain [query]`** command - Full maintenance cycle
|
|
617
|
+
- 6-step flow: snapshot warning → status check → Coolify update → health check → reboot → final check
|
|
618
|
+
- `--skip-reboot` to skip the reboot step
|
|
619
|
+
- `--all` to maintain all servers sequentially
|
|
620
|
+
- `--dry-run` to preview maintenance steps
|
|
621
|
+
- **`quicklify remove [query]`** command - Remove a server from local config without destroying the cloud server
|
|
622
|
+
- Accepts server name or IP address
|
|
623
|
+
- Confirmation prompt before removal
|
|
624
|
+
- **`--all` flag** on `status`, `update`, `backup` commands
|
|
625
|
+
- `status --all`: parallel status check with table output (Promise.all)
|
|
626
|
+
- `update --all`: sequential update with single confirmation prompt
|
|
627
|
+
- `backup --all`: sequential backup across all servers
|
|
628
|
+
- **`status --autostart`** flag - Restarts Coolify via SSH if server is running but Coolify is down
|
|
629
|
+
- Uses `docker compose restart coolify` command
|
|
630
|
+
- Waits 5 seconds and verifies Coolify came back up
|
|
631
|
+
- **`collectProviderTokens()`** utility - Deduplicates token prompts per unique provider across servers
|
|
632
|
+
- `VULTR_TOKEN` and `LINODE_TOKEN` environment variable support
|
|
633
|
+
- Vultr and Linode defaults in all 3 templates (starter, production, dev)
|
|
634
|
+
- `"vultr"` and `"linode"` in YAML config validation
|
|
635
|
+
- 195 new tests across 6 new test files + enhanced existing test files
|
|
636
|
+
|
|
637
|
+
### Changed
|
|
638
|
+
- Provider selection now shows 4 choices: Hetzner Cloud, DigitalOcean, Vultr, Linode (Akamai)
|
|
639
|
+
- Provider factory supports `"vultr"` and `"linode"` cases
|
|
640
|
+
- Total commands: 19 → 23 (add, maintain, remove + maintain --all)
|
|
641
|
+
- Test count: 742 → 937
|
|
642
|
+
- Test suites: 40 → 44
|
|
643
|
+
- Coverage: 98%+ statements, 91%+ branches, 98%+ functions
|
|
644
|
+
- Zero new npm dependencies added
|
|
645
|
+
|
|
646
|
+
## [0.9.0] - 2026-02-21
|
|
647
|
+
|
|
648
|
+
### Added
|
|
649
|
+
- **`--config <path>`** flag on `quicklify init` - Load deployment parameters from a YAML config file
|
|
650
|
+
- Supports all init options: provider, region, size, name, fullSetup, template, domain
|
|
651
|
+
- Validates config with detailed warnings for invalid values
|
|
652
|
+
- Security: detects and warns about token fields in config files
|
|
653
|
+
- Handles missing files and invalid YAML syntax gracefully
|
|
654
|
+
- **`--template <name>`** flag on `quicklify init` - Use predefined server templates
|
|
655
|
+
- `starter` - Minimal setup (cheapest option, no hardening)
|
|
656
|
+
- `production` - Production-ready (larger server, auto firewall + SSH hardening)
|
|
657
|
+
- `dev` - Development/testing (cheap, no hardening)
|
|
658
|
+
- Per-provider defaults: Hetzner and DigitalOcean have optimized region/size pairs
|
|
659
|
+
- **Config merge system** with priority: CLI flags > YAML config > template defaults > interactive prompts
|
|
660
|
+
- `QuicklifyYamlConfig`, `TemplateName`, `TemplateDefinition` TypeScript interfaces
|
|
661
|
+
- `src/utils/templates.ts` - Template definitions with per-provider defaults
|
|
662
|
+
- `src/utils/yamlConfig.ts` - YAML config loader with validation and security checks
|
|
663
|
+
- `src/utils/configMerge.ts` - Multi-source config merge logic
|
|
664
|
+
- 106 new tests across 4 new test files (templates, yamlConfig, configMerge, init-config E2E)
|
|
665
|
+
|
|
666
|
+
### Changed
|
|
667
|
+
- `InitOptions` interface extended with `config` and `template` fields
|
|
668
|
+
- `initCommand()` now processes YAML config and template before main flow
|
|
669
|
+
- Total commands: 19 (unchanged)
|
|
670
|
+
- Test count: 636 → 742
|
|
671
|
+
- Test suites: 36 → 40
|
|
672
|
+
- Coverage: 98%+ statements, 91%+ branches, 98%+ functions
|
|
673
|
+
|
|
674
|
+
### Dependencies
|
|
675
|
+
- Added `js-yaml` (runtime) + `@types/js-yaml` (dev) - YAML parsing
|
|
676
|
+
|
|
677
|
+
## [0.8.0] - 2026-02-21
|
|
678
|
+
|
|
679
|
+
### Added
|
|
680
|
+
- **`quicklify backup [query]`** command - Backup Coolify database and config files
|
|
681
|
+
- `pg_dump` + gzip for PostgreSQL database backup
|
|
682
|
+
- Config tarball (`.env`, `docker-compose.yml`, `docker-compose.prod.yml`)
|
|
683
|
+
- SCP download to `~/.quicklify/backups/{server-name}/{timestamp}/`
|
|
684
|
+
- `manifest.json` with server info, Coolify version, file list
|
|
685
|
+
- `--dry-run` flag to preview backup steps
|
|
686
|
+
- **`quicklify restore [query]`** command - Restore Coolify from a backup
|
|
687
|
+
- Interactive backup selection from available backups
|
|
688
|
+
- `--backup <timestamp>` flag to skip selection prompt
|
|
689
|
+
- Double confirmation safety (confirm + type server name)
|
|
690
|
+
- Full restore flow: upload → stop Coolify → start DB → restore DB → restore config → start Coolify
|
|
691
|
+
- `--dry-run` flag to preview restore steps
|
|
692
|
+
- **`quicklify export [path]`** command - Export server list to JSON file
|
|
693
|
+
- Default path: `./quicklify-export.json`
|
|
694
|
+
- Custom path: `quicklify export /path/to/file.json`
|
|
695
|
+
- **`quicklify import <path>`** command - Import servers from JSON file
|
|
696
|
+
- Format validation with field-level checking
|
|
697
|
+
- Duplicate detection by server ID (skips existing)
|
|
698
|
+
- **`--full-setup` flag** on `quicklify init` - Auto-configure firewall + SSH hardening after deploy
|
|
699
|
+
- Runs `firewallSetup()` + `secureSetup(force=true)` after Coolify health check
|
|
700
|
+
- Skips interactive confirmations in automated mode
|
|
701
|
+
- `BackupManifest` TypeScript interface
|
|
702
|
+
- `BACKUPS_DIR` config constant (`~/.quicklify/backups/`)
|
|
703
|
+
- `validateServerRecords()` pure function for import validation
|
|
704
|
+
- `scpDownload()` and `scpUpload()` SCP helpers using `spawn`
|
|
705
|
+
- `loadManifest()` and `listBackups()` backup utility functions
|
|
706
|
+
- Pure command builder functions for all backup/restore SSH operations
|
|
707
|
+
- 137 new tests across 4 new test files + 6 enhanced test files
|
|
708
|
+
- Provider test coverage: uploadSshKey, rebootServer, createServer with sshKeyIds
|
|
709
|
+
- Doctor, monitor, restart, status, healthCheck, ssh edge case coverage
|
|
710
|
+
|
|
711
|
+
### Changed
|
|
712
|
+
- `firewallSetup()` now exported from `firewall.ts` (was private)
|
|
713
|
+
- `secureSetup()` now exported from `secure.ts` with `force` parameter to skip prompts
|
|
714
|
+
- Total commands: 15 → 19 (backup, restore, export, import)
|
|
715
|
+
- Test count: 499 → 636
|
|
716
|
+
- Test suites: 32 → 36
|
|
717
|
+
- Coverage: 98%+ statements, 90%+ branches, 98%+ functions
|
|
718
|
+
- Zero new npm dependencies added
|
|
719
|
+
|
|
720
|
+
## [0.7.2] - 2026-02-21
|
|
721
|
+
|
|
722
|
+
### Added
|
|
723
|
+
- **Auto SSH key upload** during `quicklify init` — detects local SSH key (`~/.ssh/id_ed25519.pub`, `id_rsa.pub`, `id_ecdsa.pub`) and uploads to provider (DigitalOcean/Hetzner) automatically. Eliminates password requirement on first SSH login
|
|
724
|
+
- **Auto SSH key generation** — if no SSH key exists, generates ed25519 key pair automatically
|
|
725
|
+
- **Local config cleanup on destroy failure** — when `quicklify destroy` fails (server already deleted), prompts to remove from local config
|
|
726
|
+
|
|
727
|
+
### Fixed
|
|
728
|
+
- **Fail2ban heredoc bug** — heredoc delimiter was not recognized when joined with `&&` chain, causing invalid config file and fail2ban crash. Replaced with `printf`
|
|
729
|
+
- **Fail2ban systemd backend** — added `python3-systemd` package (required for `backend = systemd` on Ubuntu)
|
|
730
|
+
|
|
731
|
+
## [0.7.1] - 2026-02-20
|
|
732
|
+
|
|
733
|
+
### Fixed
|
|
734
|
+
- **Domain command rewritten for Coolify v4** - Uses PostgreSQL `instance_settings` table instead of `.env` APP_URL
|
|
735
|
+
- Domain add now uses `docker compose -f docker-compose.yml -f docker-compose.prod.yml restart` (fixes compose error)
|
|
736
|
+
- Coolify existence check uses `docker ps` container check instead of `.env` file check
|
|
737
|
+
- DNS check fallback to `getent ahosts` (works on servers without `dig`/`dnsutils`)
|
|
738
|
+
- SSH restart compatibility: fallback `systemctl restart ssh` for Ubuntu/Debian (was `sshd` only)
|
|
739
|
+
|
|
740
|
+
## [0.7.0] - 2026-02-20
|
|
741
|
+
|
|
742
|
+
### Added
|
|
743
|
+
- **`quicklify firewall [subcommand]`** command - Manage server firewall (UFW)
|
|
744
|
+
- `setup` - Install UFW + configure Coolify ports (80, 443, 8000, 6001, 6002) + SSH (22)
|
|
745
|
+
- `add` - Open a port (`--port`, `--protocol tcp|udp`)
|
|
746
|
+
- `remove` - Close a port (port 22 protected, Coolify ports warn before removal)
|
|
747
|
+
- `list` - Show current firewall rules
|
|
748
|
+
- `status` - Check UFW active/inactive state
|
|
749
|
+
- **`quicklify domain [subcommand]`** command - Manage server domain and SSL
|
|
750
|
+
- `add` - Bind domain to Coolify (`--domain`, `--no-ssl` to disable HTTPS)
|
|
751
|
+
- `remove` - Remove domain, revert to IP:8000
|
|
752
|
+
- `check` - Verify DNS A record matches server IP
|
|
753
|
+
- `list` - Show current APP_URL configuration
|
|
754
|
+
- **`quicklify secure [subcommand]`** command - SSH hardening and fail2ban
|
|
755
|
+
- `setup` - Disable password auth, set root login to key-only, install fail2ban (requires SSH key check + double confirmation)
|
|
756
|
+
- `status` - Show current SSH security settings
|
|
757
|
+
- `audit` - Detailed security report with score (0-4)
|
|
758
|
+
- `--dry-run` flag on all three commands - Preview commands without executing
|
|
759
|
+
- Protected port system: port 22 cannot be removed via `firewall remove`
|
|
760
|
+
- Coolify port warnings: removing ports 80/443/8000/6001/6002 requires confirmation
|
|
761
|
+
- SSH key safety check: `secure setup` refuses to run if no authorized_keys found
|
|
762
|
+
- Pure functions for all commands (unit-testable): `isValidPort`, `isProtectedPort`, `buildUfwRuleCommand`, `parseUfwStatus`, `isValidDomain`, `sanitizeDomain`, `buildSetFqdnCommand`, `parseDnsResult`, `parseFqdn`, `parseSshdConfig`, `parseAuditResult`, `buildHardeningCommand`, `buildFail2banCommand`
|
|
763
|
+
- `FirewallRule`, `FirewallStatus`, `SshdSetting`, `SecureAuditResult` TypeScript interfaces
|
|
764
|
+
- 140 new tests across 3 test files (firewall, domain, secure)
|
|
765
|
+
|
|
766
|
+
### Changed
|
|
767
|
+
- Total commands: 12 → 15
|
|
768
|
+
- Test count: 354 → 494
|
|
769
|
+
- Test suites: 29 → 32
|
|
770
|
+
- Coverage maintained: 97%+ statements, 85%+ branches, 96%+ functions
|
|
771
|
+
- Zero new npm dependencies added
|
|
772
|
+
|
|
773
|
+
## [0.6.0] - 2026-02-20
|
|
774
|
+
|
|
775
|
+
### Added
|
|
776
|
+
- **`quicklify logs [query]`** command - View Coolify, Docker, or system logs via SSH
|
|
777
|
+
- `--lines N` (default 50), `--follow` (real-time streaming), `--service coolify|docker|system`
|
|
778
|
+
- **`quicklify monitor [query]`** command - Show CPU, RAM, Disk usage via SSH
|
|
779
|
+
- `--containers` flag to display Docker container list
|
|
780
|
+
- **`quicklify health`** command - Bulk health check of all registered servers
|
|
781
|
+
- Parallel HTTP checks with response time measurement and table output
|
|
782
|
+
- **`quicklify doctor`** command - Local environment diagnostics
|
|
783
|
+
- Checks Node.js version, npm, SSH client, config directory, registered servers
|
|
784
|
+
- `--check-tokens` flag for future provider token validation
|
|
785
|
+
- `sshStream()` SSH helper - Spawns SSH with `stdio: "inherit"` for real-time log streaming
|
|
786
|
+
- `parseMetrics()` pure function for parsing `top`/`free`/`df` output
|
|
787
|
+
- `buildLogCommand()` pure function for service-to-command mapping
|
|
788
|
+
- `checkServerHealth()` function for individual server HTTP health checks
|
|
789
|
+
- 43 new tests across 5 test files (doctor, health-command, logs, monitor, ssh-utils)
|
|
790
|
+
|
|
791
|
+
### Changed
|
|
792
|
+
- Test count: 311 → 354
|
|
793
|
+
- Test suites: 25 → 29
|
|
794
|
+
- Coverage maintained: 97%+ statements, 87%+ branches, 96%+ functions
|
|
795
|
+
- Zero new npm dependencies added
|
|
796
|
+
|
|
797
|
+
## [0.5.0] - 2026-02-20
|
|
798
|
+
|
|
799
|
+
### Added
|
|
800
|
+
- **`quicklify config`** command - Manage default configuration (`set`, `get`, `list`, `reset`)
|
|
801
|
+
- **`quicklify ssh [query]`** command - SSH into a registered server (interactive or `--command` mode)
|
|
802
|
+
- **`quicklify update [query]`** command - Update Coolify on a registered server via SSH
|
|
803
|
+
- **`quicklify restart [query]`** command - Restart a server via provider API (Hetzner + DigitalOcean)
|
|
804
|
+
- `rebootServer()` method on `CloudProvider` interface (Hetzner + DigitalOcean implementations)
|
|
805
|
+
- Shared `resolveServer()` and `promptApiToken()` utilities (`src/utils/serverSelect.ts`)
|
|
806
|
+
- Default config management via `~/.quicklify/config.json` (`src/utils/defaults.ts`)
|
|
807
|
+
- SSH helper utilities: `checkSshAvailable()`, `sshConnect()`, `sshExec()` (`src/utils/ssh.ts`)
|
|
808
|
+
- `QuicklifyConfig` TypeScript interface
|
|
809
|
+
- 65 new tests across 7 new test files
|
|
810
|
+
- SSH availability detection for Windows/Linux/macOS
|
|
811
|
+
|
|
812
|
+
### Changed
|
|
813
|
+
- Extracted duplicate `selectServer()` into shared utility (DRY refactor)
|
|
814
|
+
- Refactored `status` and `destroy` commands to use shared `resolveServer` + `promptApiToken`
|
|
815
|
+
- Test count: 246 → 311
|
|
816
|
+
- Coverage maintained: 97%+ statements, 88%+ branches
|
|
817
|
+
|
|
818
|
+
## [0.4.1] - 2026-02-20
|
|
819
|
+
|
|
820
|
+
### Security
|
|
821
|
+
- **Environment variable token support** - Use `HETZNER_TOKEN` / `DIGITALOCEAN_TOKEN` env vars instead of `--token` flag to avoid shell history and `ps aux` exposure
|
|
822
|
+
- Config directory (`~/.quicklify/`) created with `0o700` permissions (owner only)
|
|
823
|
+
- Cloud-init install log restricted to `chmod 600` (root read/write only)
|
|
824
|
+
- Server name validation strengthened: 3-63 chars, must start with letter, end with letter/number
|
|
825
|
+
- SSL/HTTPS setup warnings added to `init` and `status` command output
|
|
826
|
+
- Updated `SECURITY.md` with current security measures and DigitalOcean API v2
|
|
827
|
+
|
|
828
|
+
### Changed
|
|
829
|
+
- ESLint upgraded from v9 to v10 (new `preserve-caught-error` rule compliance)
|
|
830
|
+
- Updated dependencies: axios 1.13, chalk 5.6, commander 14, ora 9, tsx 4.21, typescript 5.9
|
|
831
|
+
- Minimum Node.js version: 20 (ESLint 10 + ora 9 + commander 14 requirement)
|
|
832
|
+
- CI matrix: 3 OS x 2 Node versions (dropped Node 18)
|
|
833
|
+
- Non-interactive mode now detected by `--provider` flag alone (token can come from env var)
|
|
834
|
+
- `--token` option description updated to mention env var alternatives
|
|
835
|
+
|
|
836
|
+
## [0.4.0] - 2026-02-20
|
|
837
|
+
|
|
838
|
+
### Added
|
|
839
|
+
- **`quicklify list`** command - List all registered servers (no token required)
|
|
840
|
+
- **`quicklify status [query]`** command - Check server and Coolify status by IP or name
|
|
841
|
+
- **`quicklify destroy [query]`** command - Destroy a server with double confirmation safety
|
|
842
|
+
- **Non-interactive mode** for `quicklify init` with `--provider`, `--token`, `--region`, `--size`, `--name` flags
|
|
843
|
+
- **Coolify health check polling** - Replaces blind wait with intelligent `http://IP:8000` polling
|
|
844
|
+
- **Server record persistence** - Successful deploys saved to `~/.quicklify/servers.json`
|
|
845
|
+
- `ServerRecord` and `InitOptions` TypeScript interfaces
|
|
846
|
+
- `src/utils/config.ts` - Config module for server record CRUD (`getServers`, `saveServer`, `removeServer`, `findServer`)
|
|
847
|
+
- `src/utils/providerFactory.ts` - Provider factory extracted from init.ts for better testability
|
|
848
|
+
- `src/utils/healthCheck.ts` - `waitForCoolify()` with configurable polling (min wait + 5s interval + max attempts)
|
|
849
|
+
- `destroyServer()` method on `CloudProvider` interface (Hetzner + DigitalOcean implementations)
|
|
850
|
+
- 86 new tests: config, list, status, destroy, healthCheck, providerFactory, edge cases, E2E flows
|
|
851
|
+
- Edge case test coverage: config corruption, health check retries, non-interactive validation
|
|
852
|
+
|
|
853
|
+
### Changed
|
|
854
|
+
- `initCommand` now accepts `InitOptions` parameter for non-interactive mode
|
|
855
|
+
- Init flow uses `waitForCoolify()` instead of fixed `setTimeout` (faster with early exit on success)
|
|
856
|
+
- Init flow saves server record to local config after successful deploy
|
|
857
|
+
- Success message now includes `quicklify status` and `quicklify list` hints
|
|
858
|
+
- Provider creation extracted to `providerFactory.ts` (no behavior change)
|
|
859
|
+
- Test count: 145 → 233
|
|
860
|
+
- Coverage maintained: 97%+ statements, 89%+ branches, 96%+ functions
|
|
861
|
+
|
|
862
|
+
### Fixed
|
|
863
|
+
- Non-interactive mode properly exits with code 1 on invalid provider or token
|
|
864
|
+
- Health check accepts any HTTP response (200, 302, 401, 500) as "Coolify is running"
|
|
865
|
+
- `destroy` now removes local config record when server already deleted from provider ("not found")
|
|
866
|
+
|
|
867
|
+
## [0.3.1] - 2026-02-19
|
|
868
|
+
|
|
869
|
+
### Fixed
|
|
870
|
+
- Hetzner pricing now shows net prices (excl. VAT) matching website display
|
|
871
|
+
- Hetzner server types filtered by `/datacenters` API for real availability
|
|
872
|
+
- Replaced deprecated Hetzner server types (cpx→cx23/cx33, per Jan 2026 deprecation)
|
|
873
|
+
- "Server name already used" error now prompts for a new name instead of crashing
|
|
874
|
+
- Location disabled retry now re-prompts for both region and server type
|
|
875
|
+
- Back navigation in error retry flows (server type → region)
|
|
876
|
+
- Updated static fallback prices to match current Hetzner net pricing
|
|
877
|
+
|
|
878
|
+
### Changed
|
|
879
|
+
- `getLocationConfig` now accepts `exclude` parameter to filter disabled locations
|
|
880
|
+
|
|
881
|
+
## [0.3.0] - 2026-02-19
|
|
882
|
+
|
|
883
|
+
### Added
|
|
884
|
+
- DigitalOcean provider implementation (full API integration)
|
|
885
|
+
- Provider selection UI prompt (Hetzner Cloud / DigitalOcean)
|
|
886
|
+
- `getProviderConfig()` prompt function
|
|
887
|
+
- DigitalOcean-specific interfaces (`DORegion`, `DOSize`, `DOErrorResponse`)
|
|
888
|
+
- Step-based back navigation with `← Back` option in all prompts
|
|
889
|
+
- `getServerDetails()` + IP refresh for DigitalOcean delayed IP assignment
|
|
890
|
+
- Minimum 2GB RAM + 2 vCPU filter for Coolify requirements
|
|
891
|
+
- Network connectivity wait loop in cloud-init (DigitalOcean cloud-init timing fix)
|
|
892
|
+
- Installation logging to `/var/log/quicklify-install.log` for troubleshooting
|
|
893
|
+
- Troubleshooting info in deployment success message
|
|
894
|
+
- Location retry on "server location disabled" error (offers region change)
|
|
895
|
+
- 50+ new tests (DigitalOcean integration, provider selection, E2E flows)
|
|
896
|
+
|
|
897
|
+
### Changed
|
|
898
|
+
- `init` command now prompts for provider selection instead of defaulting to Hetzner
|
|
899
|
+
- DigitalOcean image changed from Ubuntu 24.04 to 22.04 (stable cloud-init support)
|
|
900
|
+
- Hetzner server type filtering now uses `/datacenters` API for real availability
|
|
901
|
+
- Replaced deprecated Hetzner server types (cpx→cx23/cx33, per Jan 2026 deprecation)
|
|
902
|
+
- Provider-specific deployment timing (Hetzner ~5 min, DigitalOcean ~7 min)
|
|
903
|
+
- Cloud-init script now uses `set +e` for resilient execution
|
|
904
|
+
- UFW firewall support for DigitalOcean (alongside iptables for Hetzner)
|
|
905
|
+
- Updated `typescript-eslint` from 8.55 to 8.56
|
|
906
|
+
- Test count: 95 → 143+
|
|
907
|
+
|
|
908
|
+
### Fixed
|
|
909
|
+
- Hetzner deprecated server types (cpx11, cx22 etc.) shown but failing on creation
|
|
910
|
+
- DigitalOcean cloud-init failing due to network not ready at script execution time
|
|
911
|
+
- Hetzner pricing now shows net prices (excl. VAT) matching website display
|
|
912
|
+
- Coverage gaps in Hetzner provider (price null fallback, error.data.error undefined)
|
|
913
|
+
|
|
914
|
+
## [0.2.8] - 2026-02-16
|
|
915
|
+
|
|
916
|
+
### Added
|
|
917
|
+
- ESLint 9 + typescript-eslint 8 + Prettier setup with npm scripts
|
|
918
|
+
- `.prettierrc` and `eslint.config.js` configuration files
|
|
919
|
+
- `CHANGELOG.md` with full version history
|
|
920
|
+
- `CONTRIBUTING.md` with development guide and PR process
|
|
921
|
+
- Proper TypeScript interfaces for Hetzner API responses (`HetznerLocation`, `HetznerServerType`, `HetznerPrice`, `HetznerErrorResponse`)
|
|
922
|
+
- `isAxiosError` mock in test helpers
|
|
923
|
+
|
|
924
|
+
### Changed
|
|
925
|
+
- Replaced all `catch (error: any)` with `catch (error: unknown)` + proper type guards
|
|
926
|
+
- Replaced `any` type annotations with proper interfaces in Hetzner provider
|
|
927
|
+
- Applied Prettier formatting across all source files
|
|
928
|
+
|
|
929
|
+
## [0.2.7] - 2026-02-16
|
|
930
|
+
|
|
931
|
+
### Changed
|
|
932
|
+
- Updated README with accurate feature descriptions and missing version history
|
|
933
|
+
- Fixed inaccurate SECURITY.md claims (token handling, SDK references)
|
|
934
|
+
- Added npm keywords for better discoverability (vps, cloud, automation, self-hosted, paas, devops, server)
|
|
935
|
+
|
|
936
|
+
### Security
|
|
937
|
+
- Added server name sanitization in cloud-init script (defense-in-depth)
|
|
938
|
+
|
|
939
|
+
## [0.2.6] - 2026-02-16
|
|
940
|
+
|
|
941
|
+
### Changed
|
|
942
|
+
- CI: Upgraded Codecov action to v5
|
|
943
|
+
|
|
944
|
+
## [0.2.5] - 2026-02-16
|
|
945
|
+
|
|
946
|
+
### Added
|
|
947
|
+
- CI: Codecov integration for automatic coverage badge
|
|
948
|
+
|
|
949
|
+
## [0.2.4] - 2026-02-15
|
|
950
|
+
|
|
951
|
+
### Changed
|
|
952
|
+
- Refactor: Removed recommended label from server type selection
|
|
953
|
+
- Excluded failed server types from retry list
|
|
954
|
+
|
|
955
|
+
## [0.2.3] - 2026-02-15
|
|
956
|
+
|
|
957
|
+
### Fixed
|
|
958
|
+
- Unsupported server type error now triggers retry
|
|
959
|
+
- Dynamic deployment summary based on actual server config
|
|
960
|
+
- Dynamic recommended server type selection
|
|
961
|
+
|
|
962
|
+
## [0.2.2] - 2026-02-15
|
|
963
|
+
|
|
964
|
+
### Added
|
|
965
|
+
- Deprecated server type filtering
|
|
966
|
+
- Retry mechanism for unavailable server types
|
|
967
|
+
|
|
968
|
+
## [0.2.1] - 2026-02-14
|
|
969
|
+
|
|
970
|
+
### Fixed
|
|
971
|
+
- URL protocol changed from https to http for initial Coolify setup
|
|
972
|
+
|
|
973
|
+
## [0.2.0] - 2026-02-14
|
|
974
|
+
|
|
975
|
+
### Added
|
|
976
|
+
- Dynamic server type filtering based on selected location
|
|
977
|
+
- Auto firewall configuration (ports 8000, 22, 80, 443)
|
|
978
|
+
|
|
979
|
+
### Changed
|
|
980
|
+
- Improved price formatting
|
|
981
|
+
|
|
982
|
+
### Removed
|
|
983
|
+
- Debug logs
|
|
984
|
+
|
|
985
|
+
## [0.1.11] - 2026-02-14
|
|
986
|
+
|
|
987
|
+
### Changed
|
|
988
|
+
- Removed tracked Claude Code local settings
|
|
989
|
+
|
|
990
|
+
### Added
|
|
991
|
+
- Firewall rules to cloud-init
|
|
992
|
+
- Security notes to README
|
|
993
|
+
|
|
994
|
+
## [0.1.10] - 2026-02-14
|
|
995
|
+
|
|
996
|
+
### Fixed
|
|
997
|
+
- Updated deploy time estimate from 60 seconds to 4 minutes
|
|
998
|
+
|
|
999
|
+
## [0.1.9] - 2026-02-14
|
|
1000
|
+
|
|
1001
|
+
### Fixed
|
|
1002
|
+
- Read version from package.json dynamically
|
|
1003
|
+
|
|
1004
|
+
## [0.1.8] - 2026-02-14
|
|
1005
|
+
|
|
1006
|
+
### Fixed
|
|
1007
|
+
- Added build step to publish workflow
|
|
1008
|
+
|
|
1009
|
+
## [0.1.7] - 2026-02-14
|
|
1010
|
+
|
|
1011
|
+
### Fixed
|
|
1012
|
+
- Added .npmignore to include dist/ in npm package
|
|
1013
|
+
|
|
1014
|
+
## [0.1.6] - 2026-02-14
|
|
1015
|
+
|
|
1016
|
+
### Fixed
|
|
1017
|
+
- Added bin wrapper for Windows npx compatibility
|
|
1018
|
+
|
|
1019
|
+
## [0.1.5] - 2026-02-14
|
|
1020
|
+
|
|
1021
|
+
### Fixed
|
|
1022
|
+
- Added files field to include dist/ in npm package
|
|
1023
|
+
|
|
1024
|
+
## [0.1.4] - 2026-02-14
|
|
1025
|
+
|
|
1026
|
+
### Added
|
|
1027
|
+
- SECURITY.md with security policy
|
|
1028
|
+
- Socket.dev security badge
|
|
1029
|
+
- Package.json metadata (repository, bugs, homepage, author)
|
|
1030
|
+
|
|
1031
|
+
## [0.1.3] - 2026-02-14
|
|
1032
|
+
|
|
1033
|
+
### Added
|
|
1034
|
+
- Auto npm publish workflow via GitHub Actions
|
|
1035
|
+
- GitHub stars badge to README
|
|
1036
|
+
|
|
1037
|
+
## [0.1.2] - 2026-02-14
|
|
1038
|
+
|
|
1039
|
+
### Changed
|
|
1040
|
+
- Updated deploy time references from 60s to 4 minutes
|
|
1041
|
+
|
|
1042
|
+
## [0.1.1] - 2026-02-14
|
|
1043
|
+
|
|
1044
|
+
### Fixed
|
|
1045
|
+
- Corrected bin field in package.json
|
|
1046
|
+
- Added status badges to README
|
|
1047
|
+
|
|
1048
|
+
## [0.1.0] - 2026-02-14
|
|
1049
|
+
|
|
1050
|
+
### Added
|
|
1051
|
+
- Initial release
|
|
1052
|
+
- Hetzner Cloud integration
|
|
1053
|
+
- Interactive CLI with Commander.js + Inquirer.js
|
|
1054
|
+
- Automated Coolify installation via cloud-init
|
|
1055
|
+
- ARM64 support
|
|
1056
|
+
- Full test suite (unit, integration, e2e)
|