'no query']); exit; } $results = []; $iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($VAULT)); foreach ($iter as $file) { if ($file->getExtension() !== 'md') continue; $content = file_get_contents($file->getPathname()); if (stripos($content, $q) !== false) { $rel = str_replace($VAULT . '/', '', $file->getPathname()); // Extract frontmatter tags preg_match('/tags:\s*\[([^\]]+)\]/', $content, $tm); $results[] = [ 'file' => $rel, 'tags' => trim($tm[1] ?? ''), 'snippet' => substr(strip_tags($content), 0, 200), 'size' => strlen($content) ]; } } echo json_encode(['query' => $q, 'results' => $results, 'count' => count($results)]); break; case 'read': $file = $_GET['file'] ?? ''; $path = realpath($VAULT . '/' . $file); if (!$path || strpos($path, $VAULT) !== 0 || !file_exists($path)) { echo json_encode(['error' => 'file not found']); exit; } echo json_encode(['file' => $file, 'content' => file_get_contents($path), 'size' => filesize($path)]); break; case 'list': $dir = $_GET['dir'] ?? ''; $target = realpath($VAULT . '/' . $dir) ?: $VAULT; if (strpos($target, $VAULT) !== 0) { echo json_encode(['error' => 'invalid path']); exit; } $files = []; foreach (scandir($target) as $f) { if ($f[0] === '.') continue; $full = $target . '/' . $f; $files[] = ['name' => $f, 'type' => is_dir($full) ? 'dir' : 'file', 'size' => is_file($full) ? filesize($full) : 0]; } echo json_encode(['dir' => $dir ?: '/', 'files' => $files, 'count' => count($files)]); break; case 'write': $file = $_POST['file'] ?? ''; $content = $_POST['content'] ?? ''; if (!$file || !$content) { echo json_encode(['error' => 'file and content required']); exit; } $path = $VAULT . '/' . $file; $dir = dirname($path); if (!is_dir($dir)) mkdir($dir, 0755, true); file_put_contents($path, $content); echo json_encode(['ok' => true, 'file' => $file, 'size' => strlen($content)]); break; case 'stats': $count = 0; $total = 0; $dirs = []; $iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($VAULT)); foreach ($iter as $f) { if ($f->getExtension() === 'md') { $count++; $total += $f->getSize(); } } foreach (scandir($VAULT) as $d) { if ($d[0] !== '.' && is_dir("$VAULT/$d")) { $n = count(glob("$VAULT/$d/*.md")); $dirs[] = ['name' => $d, 'files' => $n]; } } echo json_encode(['vault' => $VAULT, 'files' => $count, 'total_bytes' => $total, 'bytes' => $total, 'size' => $total, 'size_kb' => round($total/1024), 'size_human' => $total >= 1048576 ? round($total/1048576,1).' MB' : round($total/1024).' KB', 'dirs' => $dirs]); break; default: echo json_encode(['error' => 'unknown action', 'actions' => ['search','read','list','write','stats']]); }