# Flynn Makefile # Self-hosted personal AI agent .PHONY: build dev start stop restart status logs tui tui-fs tui-dev test test-run lint typecheck check help deps install daemon-start daemon-stop daemon-restart daemon-status daemon-logs enable disable llama-start llama-stop llama-restart llama-status llama-logs llama-enable llama-disable llamacpp-start llamacpp-stop llamacpp-restart llamacpp-status llamacpp-logs llamacpp-enable llamacpp-disable ollama-start ollama-stop ollama-restart ollama-status ollama-logs ollama-enable ollama-disable compose-up compose-down compose-restart compose-logs compose-ps compose-pull whisper-start whisper-stop whisper-restart whisper-logs brave-start brave-stop brave-restart brave-logs searxng-start searxng-stop searxng-restart searxng-logs skills-list skills-info skills-install skills-uninstall skills-refresh # Default target .DEFAULT_GOAL := help # Build and development build: ## Compile TypeScript to dist/ pnpm build dev: ## Run daemon with watch mode pnpm dev start: ## Start production build (foreground) node dist/cli/index.js start # Systemd daemon management daemon-start: ## Build and start the systemd service pnpm build systemctl --user start flynn.service @echo "Flynn daemon built and started" daemon-stop: ## Stop the systemd service systemctl --user stop flynn.service @echo "Flynn daemon stopped" daemon-restart: ## Build and restart the systemd service pnpm build systemctl --user restart flynn.service @echo "Flynn daemon built and restarted" daemon-status: ## Check systemd service status systemctl --user status flynn.service daemon-logs: ## Show systemd service logs journalctl --user -u flynn.service -f enable: ## Enable Flynn to start on boot systemctl --user enable flynn.service @echo "Flynn enabled to start on boot" disable: ## Disable Flynn from starting on boot systemctl --user disable flynn.service @echo "Flynn disabled from starting on boot" # Llama-server daemon management llama-start: ## Start the llama-server systemd service systemctl --user start llama-server.service @echo "Llama-server daemon started" llama-stop: ## Stop the llama-server systemd service systemctl --user stop llama-server.service @echo "Llama-server daemon stopped" llama-restart: ## Restart the llama-server systemd service systemctl --user restart llama-server.service @echo "Llama-server daemon restarted" llama-status: ## Check llama-server systemd service status systemctl --user status llama-server.service llama-logs: ## Show llama-server systemd service logs journalctl --user -u llama-server.service -f llama-enable: ## Enable llama-server to start on boot systemctl --user enable llama-server.service @echo "Llama-server enabled to start on boot" llama-disable: ## Disable llama-server from starting on boot systemctl --user disable llama-server.service @echo "Llama-server disabled from starting on boot" # LlamaCpp aliases (backward compatibility) llamacpp-start: llama-start ## Alias for llama-start llamacpp-stop: llama-stop ## Alias for llama-stop llamacpp-restart: llama-restart ## Alias for llama-restart llamacpp-status: llama-status ## Alias for llama-status llamacpp-logs: llama-logs ## Alias for llama-logs llamacpp-enable: llama-enable ## Alias for llama-enable llamacpp-disable: llama-disable ## Alias for llama-disable # Ollama daemon management ollama-start: ## Start the Ollama systemd service systemctl --user start ollama.service @echo "Ollama daemon started" ollama-stop: ## Stop the Ollama systemd service systemctl --user stop ollama.service @echo "Ollama daemon stopped" ollama-restart: ## Restart the Ollama systemd service systemctl --user restart ollama.service @echo "Ollama daemon restarted" ollama-status: ## Check Ollama systemd service status systemctl --user status ollama.service ollama-logs: ## Show Ollama systemd service logs journalctl --user -u ollama.service -f ollama-enable: ## Enable Ollama to start on boot systemctl --user enable ollama.service @echo "Ollama enabled to start on boot" ollama-disable: ## Disable Ollama from starting on boot systemctl --user disable ollama.service @echo "Ollama disabled from starting on boot" # Aliases for convenience stop: daemon-stop ## Alias for daemon-stop restart: daemon-restart ## Alias for daemon-restart status: daemon-status ## Alias for daemon-status logs: daemon-logs ## Alias for daemon-logs # Docker Compose dependencies compose-up: ## Start docker-compose services (usage: make compose-up [SERVICE=name] [PROFILE=name]) @set -e; \ if [ -n "$(SERVICE)" ]; then \ docker compose -f docker-compose.yml up -d "$(SERVICE)"; \ elif [ -n "$(PROFILE)" ]; then \ docker compose -f docker-compose.yml --profile "$(PROFILE)" up -d; \ else \ docker compose -f docker-compose.yml up -d; \ fi compose-down: ## Stop docker-compose services and remove containers docker compose -f docker-compose.yml down compose-restart: ## Restart docker-compose services (usage: make compose-restart [SERVICE=name]) @set -e; \ if [ -n "$(SERVICE)" ]; then \ docker compose -f docker-compose.yml restart "$(SERVICE)"; \ else \ docker compose -f docker-compose.yml restart; \ fi compose-logs: ## Stream docker-compose logs (usage: make compose-logs [SERVICE=name]) @set -e; \ if [ -n "$(SERVICE)" ]; then \ docker compose -f docker-compose.yml logs -f "$(SERVICE)"; \ else \ docker compose -f docker-compose.yml logs -f; \ fi compose-ps: ## Show docker-compose service status docker compose -f docker-compose.yml ps compose-pull: ## Pull latest docker-compose images (usage: make compose-pull [SERVICE=name]) @set -e; \ if [ -n "$(SERVICE)" ]; then \ docker compose -f docker-compose.yml pull "$(SERVICE)"; \ else \ docker compose -f docker-compose.yml pull; \ fi # Docker Compose service shortcuts whisper-start: ## Start whisper-server compose dependency docker compose -f docker-compose.yml --profile voice up -d whisper-server whisper-stop: ## Stop whisper-server compose dependency docker compose -f docker-compose.yml stop whisper-server whisper-restart: ## Restart whisper-server compose dependency docker compose -f docker-compose.yml restart whisper-server whisper-logs: ## Stream whisper-server compose logs docker compose -f docker-compose.yml logs -f whisper-server brave-start: ## Start brave-search compose dependency docker compose -f docker-compose.yml --profile search up -d brave-search brave-stop: ## Stop brave-search compose dependency docker compose -f docker-compose.yml stop brave-search brave-restart: ## Restart brave-search compose dependency docker compose -f docker-compose.yml restart brave-search brave-logs: ## Stream brave-search compose logs docker compose -f docker-compose.yml logs -f brave-search searxng-start: ## Start searxng compose dependency docker compose -f docker-compose.yml --profile search up -d searxng searxng-stop: ## Stop searxng compose dependency docker compose -f docker-compose.yml stop searxng searxng-restart: ## Restart searxng compose dependency docker compose -f docker-compose.yml restart searxng searxng-logs: ## Stream searxng compose logs docker compose -f docker-compose.yml logs -f searxng # TUI commands tui: ## Run TUI in minimal mode (readline) pnpm tui tui-fs: ## Run TUI in fullscreen mode (React/Ink) pnpm tui:fs tui-dev: ## Run TUI with watch mode pnpm tui:dev # Skills commands skills-list: ## List all discovered skills node dist/cli/index.js skills list skills-info: ## Show skill details (usage: make skills-info SKILL=) @test -n "$(SKILL)" || (echo "Usage: make skills-info SKILL=" && exit 1) node dist/cli/index.js skills info "$(SKILL)" skills-install: ## Install a skill (usage: make skills-install SKILL_PATH=) @test -n "$(SKILL_PATH)" || (echo "Usage: make skills-install SKILL_PATH=" && exit 1) node dist/cli/index.js skills install "$(SKILL_PATH)" skills-uninstall: ## Uninstall a skill (usage: make skills-uninstall SKILL=) @test -n "$(SKILL)" || (echo "Usage: make skills-uninstall SKILL=" && exit 1) node dist/cli/index.js skills uninstall "$(SKILL)" --yes skills-refresh: ## Refresh/discover skills from configured directories node dist/cli/index.js skills refresh # Testing test: ## Run tests in watch mode pnpm test test-run: ## Run tests once (no watch) pnpm test:run # Quality checks lint: ## Run ESLint pnpm lint typecheck: ## Run TypeScript compiler (no emit) pnpm typecheck check: lint typecheck test-run ## Run all checks (lint, typecheck, test) # Dependencies deps: ## Install dependencies pnpm install install: ## Install flynn CLI as a shell command (global link or ~/.local/bin fallback) pnpm install pnpm build @set -e; \ if pnpm link --global; then \ echo "flynn installed via pnpm global link."; \ else \ echo "pnpm global bin is not configured; installing fallback shim at $$HOME/.local/bin/flynn"; \ mkdir -p "$$HOME/.local/bin"; \ chmod +x "$(CURDIR)/dist/cli/index.js"; \ ln -sf "$(CURDIR)/dist/cli/index.js" "$$HOME/.local/bin/flynn"; \ case ":$$PATH:" in \ *":$$HOME/.local/bin:"*) echo "flynn installed at $$HOME/.local/bin/flynn";; \ *) echo "flynn installed at $$HOME/.local/bin/flynn (add $$HOME/.local/bin to PATH)";; \ esac; \ fi # Utilities help: ## Show this help message @echo "Flynn - Self-hosted personal AI agent" @echo "" @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}'