Installation
manager.php to your server — anywhere inside your web rootcomposer install. No npm. No database. No .htaccess changes required. Configuration stored automatically in writable/.manager_config.First Run — Setup Wizard
On first launch, the manager shows a full setup wizard with a cinematic dark background — animated SVG with stars, constellation lines, three rotating geometric rings, and the personal brand names TYRUS and ANGEL glowing on each side.
- Minimum 8 characters
- Live password strength meter with 7 scoring criteria
- Live password match indicator between both fields
- "Suggest strong password" button — auto-generates a secure password
- Show/hide toggle on both fields
- Full URL — used by Preview button and cache clearing
- Inline URL validation
- Logo tip: capitalize each word in your domain for multi-color logo effect
- Preset buttons: 10 / 20 / 50 / 100 / 200 GB (desktop), 3-column grid (mobile)
- Custom GB input with spinner buttons ▲▼
- Live byte conversion display
requestAnimationFrame loop.Login & Security
- Password verified against bcrypt hash in
writable/.manager_config - Brute-force protection — IP tracked in
writable/.login_attempts - Attempt 1: "Something doesn't seem right here."
- Attempt 2: "Interesting... do you continue?"
- Attempt 3: IP permanently banned — "See you in another life." — written to
writable/.blocked_ips - Session timeout — 30 minutes inactivity → auto redirect to login
- Warning bar appears 2 minutes before expiry with live countdown
- "Extend" button resets both JS timer and PHP session simultaneously
- Activity events (mousemove, keydown, click, scroll) reset inactivity counter
- All actions logged with timestamp to
writable/.activity_log— IP address logged for LOGIN and LOGOUT only
IP Ban Screen
When an IP is banned, instead of a normal error page, a full-screen animated canvas experience is shown:
- Human face drawn procedurally using
ctx.bezierCurveToandctx.ellipse - Eyes that follow the cursor in real time — pupils track mouse with clamped movement
- Random blinking with variable timing (randomized 180–480 frames)
- Periodic glitch effect —
getImageData/putImageDataslice displacement + red tint - CRT scanlines — horizontal lines at 4px intervals across the full canvas
- Radial vignette — dark edges closing in
- Custom cursor — default cursor hidden, replaced by small red dot
- Blocked: right-click, F12, Ctrl+U/I/S, Escape, scroll
- Messages with progressive fade-in (2s and 5s delays)
- Mouse leaving window: text color shifts + letter spacing expands
- Subtle breathing animation on the body element
Manager Interface
- Dynamic logo — generated from the site URL. Each word colored differently. Capitalizing words in the URL = separate color per word
- Disk usage bar — visual bar showing used / total space with exact MiB/GiB values. Cache refreshed every 5 minutes
- Animated language switcher — pill slides smoothly between EN / RO / DK (cubic-bezier). Zero page reload — full UI re-renders via
applyUiLang(). On mobile: simple bordered buttons - Header buttons: 📋 Log · ⚠ Errors · 🐘 PHP · ⌨ Shortcuts · 🔓/🔒 Root OFF/ON · ▶ Preview · 💾 Save · Logout
- Navigation — ← Back / → Forward with full history. Buttons disabled correctly at history boundaries
- Breadcrumb — clickable path segments for fast navigation
- Search files — filename search (max 100 results, case-insensitive, recursive)
- In files — toggle for content search panel
- New Folder / New File — modal with name input
- Resizable — drag border (min 160px, max 520px). Persisted in localStorage + sessionStorage. Double-click = reset to 270px
- SERVER FILES — full file/folder tree with type icons
- Favorites ⭐ — star/unstar any file or folder. Stored server-side. Inline SVG star icon in list
- Multiple selection — checkboxes + Select All. Bulk: ZIP · Download · Rename · Delete
- Bulk ZIP — create named archive from selected items
- Bulk Download — selected as ZIP, streamed directly to browser (built via
tempnam, deleted immediately after transfer) - Multi-rename — batch rename wizard for selected files
- Upload zone — drag & drop or click. Conflict modal: Replace / Keep both (auto-numbered) / Cancel
- Content search input — search inside files from sidebar
Code Editor
Built on CodeMirror 5 with 75+ CDN scripts. Theme: Dracula dark.
Special filename detection: .htaccess → shell · .env → shell · Dockerfile → dockerfile · Makefile → shell · .gitignore → shell · .babelrc / .eslintrc → JSON
- Bracket matching · Auto-close brackets · Active line highlight
- Code folding — foldGutter with 4 fold addons (brace, indent, XML, comment)
- Autocomplete — 5 hint engines (anyword, JS, CSS, HTML, XML). 400ms delay, min 3 chars, suppressed in strings/comments.
Ctrl+Space= manual - Comment/uncomment —
Ctrl+/ - Font size control — A− / A+ in bottom bar
- Custom scrollbars — macOS-style (3px transparent border)
- Image preview — jpg, jpeg, png, gif, webp, svg, ico shown inline instead of editor
- Multiple files open simultaneously
- Drag & drop reordering — left/right drop indicator with violet box-shadow
- Modified dot — visual indicator when file has unsaved changes
- Tab context menu (right-click): Close / Close Others / Close Unmodified / Close All
- Unsaved changes warning on close
- Highlights all matches simultaneously with markText
- Active match in different color — counter display:
3 / 12 - Navigate: Enter (next) / Shift+Enter (previous)
- Replace One → / Replace All ⟳
Code Analyzer / Linter
Opens as a side panel next to the editor via the 🔍 Analyze button. Supports: .php · .css · .scss · .less · .js · .ts · .jsx · .tsx
.min.js, .bundle.js, etc.) or content (avg line >300 chars). Shows friendly message with "Analyze anyway →" button.| Check | Severity | Description |
|---|---|---|
| PHP Syntax | 🔴 error | php -l via shell_exec or token_get_all() ParseError fallback |
| var_dump / print_r left in code | 🟡 warning | Debug output not removed |
| $_SERVER['PHP_SELF'] without htmlspecialchars() | 🟡 warning | XSS vulnerability |
| die()/exit() with hardcoded string | 🟡 warning | Exposes server info in production |
| $_POST/$_GET/$_REQUEST without isset() | 🟡 warning | Context-aware — 3 lines up/down checked |
| PHP function typos (118 patterns) | 🔴 error | array_mpa → array_map, jsno_encode → json_encode, etc. |
| Duplicate function definitions | 🔴 error | With first-definition line reference |
| return outside any function | 🟡 warning | Structural brace-depth analysis |
| md5() for passwords | 🟡 warning | Only when near password/pass/pwd/hash context |
| TODO / FIXME / HACK | 🔵 info | Full comment text extracted |
| Check | Severity | Description |
|---|---|---|
| Invalid CSS property | 🟡 warning | 200+ valid properties validated |
| CSS property typo | 🟡 warning | ~150 patterns, Levenshtein ≤ 3 suggestion |
| Invalid property value | 🟡 warning | Value validated against known valid options per property |
| Duplicate property in block | 🟡 warning | Same property defined twice in same block |
| Double semicolon ;; | 🟡 warning | Common typo |
| Check | Severity | Description |
|---|---|---|
| console.log left in code | 🔵 info | Remove before production |
| debugger; left in code | 🟡 warning | Stops execution in browser |
| typeof compared with == | 🟡 warning | Should use === |
| Invalid NaN comparison (=== NaN) | 🔴 error | Use Number.isNaN() or isNaN() |
| eslint-disable left in | 🔵 info | May be forgotten |
| TODO / FIXME / HACK | 🔵 info | Full comment text extracted |
ZIP Browser
Click any .zip file → opens as panel replacing the editor area.
- Expandable tree — hierarchical with depth indentation
- Cascading checkboxes — select folder = select all children recursively. Partial selection = individual files sent
- Custom hierarchical sort — folders first, files alphabetically
- Selective extraction — intelligent prefix-stripping, no unwanted nested paths
- Conflict pre-check — shows exact files that would be overwritten before extracting
- Drag & drop extraction — drag from ZIP panel onto folder in file panel. Destination folder highlights on hover
- Full extract — extract all contents at once
File Search & Content Search
Toolbar search box — recursive filename search, case-insensitive, max 100 results, instant sidebar results.
- Searches inside files — max 50 files × 5 matches per file
- Results grouped by file with match count badge
- Line number + content with search term highlighted in yellow
- Click result → opens file, jumps to exact line
- Text extensions only — skips binaries
Compare & Diff
Every save auto-creates .bak. ↕ Diff .bak shows visual diff with 3-line context. "Restore from .bak" button available.
- File 1: current editor file (automatic)
- File 2: click any file in sidebar while panel is open
- Stats:
+N added / -N removed - Color-coded: changed (amber/blue) · added (green) · removed (red) · separator (dark)
- Independent scrolling per column
Multi-Rename
- Pattern controls: Prefix · Suffix · Find · Replace (all combinable)
- Auto-numbering: 001, 002, 003...
- Live preview: old name → new name per file. Individual inputs editable
- Changed names highlighted yellow
- All renames in one operation with conflict detection
Activity Log & Error Log
Every action logged: LOGIN · LOGOUT · SAVE · UPLOAD · DELETE · RENAME · NEW FOLDER · NEW FILE · ZIP · UNZIP · UNZIP-SELECTIVE · CHMOD · CLEAR CACHE · MULTI-RENAME — with timestamp, action type, file path. IP address logged for LOGIN and LOGOUT only. Stored in writable/.activity_log as JSON. Clearable from modal.
- Parses CI4 format (
LEVEL - DATE --> MSG) and PHP standard ([date] PHP Fatal error:) log formats - Reconstructs full stack traces
- Groups by severity: Fatal · Error · Warning · Notice · Info
- Collapse/expand per group
- Stack traces displayed inline with APPPATH/SYSTEMPATH highlighting
- Reverse chronological order
Root Mode
Root OFF (default) — navigation limited to document root (public_html).
Root ON — navigate above public_html to server root. Access logs, configs, files outside web root. Warning shown as toast notification and header button changes to 🔑 Root ON when active.
Backend AJAX API
All operations via manager.php?action=ACTION:
| Action | Description |
|---|---|
| list | Directory contents — name, type, size, modified, path, permissions |
| read | File content (max 5MB) |
| readimage | Image as base64 data URI (jpg, png, gif, webp, svg, ico) |
| save | Save file — auto-creates .bak of previous version |
| upload | Upload — modes: ask / replace / copy (auto-numbered) |
| download | Download single file via HTTP |
| download-zip | Multiple files as ZIP — built via tempnam, streamed to browser, deleted immediately after |
| delete | Delete files/folders — recursive, optional .bak backup |
| rename | Rename — conflict detection, optional force overwrite |
| newfolder | Create directory (recursive mkdir) |
| newfile | Create empty file |
| zip | Create ZIP archive on server |
| zip-list | ZIP contents as hierarchical tree |
| unzip | Extract full ZIP archive |
| unzip-selective | Extract selected items with intelligent prefix-stripping |
| unzip-check | Pre-check extraction conflicts before extracting |
| chmod | Change file/folder permissions |
| search | Recursive filename search (max 100 results) |
| searchcontent | Text inside files (max 50 files × 5 matches) |
| diskusage | Disk usage — crawls 2 levels above docroot, cached 5 minutes |
| diff | File vs .bak with 3-line context |
| compare | Side-by-side diff between any two arbitrary files |
| lint | PHP/CSS/JS analysis — structured issue array |
| errorlog | Parse PHP error log (CI4 + standard format) |
| phpinfo | Parsed PHP info — version, extensions, settings |
| getfavorites | List favorited paths |
| togglefavorite | Add or remove from favorites |
| getlog | Activity log entries |
| clearlog | Clear activity log |
| clearcache | LiteSpeed purge header + CI4 writable/cache folder wipe |
| getdocroot | Server document root path |
| multirename | Batch rename with conflict detection |
Multilingual — EN / RO / DK
240+ translation keys per language. All manager UI strings translated — EN / RO / DK.
- Zero page reload switching —
switchLang()→applyUiLang()+loadFiles()+renderTabs() - All DOM elements updated: buttons, modals, placeholders, cheatsheet (fully regenerated), ZIP hints, timeout bar
- Language persisted in cookie +
writable/.manager_config - Animated pill switcher (desktop): cubic-bezier slide, no-transition on init to avoid flash
Mobile & Responsive
| Breakpoint | Behavior |
|---|---|
| < 425px | Log hidden, disk bar hidden, micro buttons 8px, simple lang switcher |
| 425–599px | Log appears first (order:-1) before Errors |
| 600–1023px | Lang switcher static in header (no absolute positioning) |
| 1024–1100px | Lang switcher static, compact toolbar |
| > 1100px | Full desktop layout, animated pill centered absolute |
- Sidebar drawer — slides from left, overlay to close, auto-closes on file open / ZIP / image, stays open on folder navigate
- Long press 500ms — context menu at touch position, haptic feedback (
navigator.vibrate(30)), move finger = cancel - Tab system — max-width 90px, ellipsis, close always visible, horizontal scroll
- Diff/Compare — hidden under 768px (insufficient space for split view)
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
| Ctrl + S | Save current file |
| Ctrl + W | Close current tab |
| Ctrl + Z | Undo |
| Ctrl + Y | Redo |
| Ctrl + F | Find in file |
| Ctrl + H | Find & Replace |
| Ctrl + / | Comment / uncomment line |
| Tab | Indent selection |
| Ctrl + Space | Manual autocomplete |
| Escape | Close autocomplete / modal |
| A+ / A− | Increase / decrease font size |
| Right-click file | Context menu |
| Right-click tab | Tab context menu |
| Drag tab | Reorder tabs |
| Drag sidebar border | Resize sidebar |
| Double-click border | Reset sidebar width to default |
Requirements
- PHP 8.0 or higher — tested up to PHP 8.4 (requires PHP 8.0+ for
str_starts_with()) - ZipArchive extension — available on most shared hosting by default
writable/directory must be writable — auto-created on first run- No Composer · No npm · No database · No framework