From a8dd432fd58a3036cf952eec691981dff43a7c7e Mon Sep 17 00:00:00 2001 From: soryu Date: Sun, 22 Feb 2026 16:39:15 +0000 Subject: fix: remove duplicate daemon page, add ARM64 binary, use makima.jp URLs (#78) * feat: soryu-co/soryu - makima: Add macOS ARM64 binary to daemon download bundle * feat: soryu-co/soryu - makima: Remove duplicate Daemon nav entry and route * feat: soryu-co/soryu - makima: Update download URLs to use makima.jp hosted instance --- .github/workflows/release.yml | 47 +- install.sh | 88 +--- makima/frontend/src/components/NavStrip.tsx | 1 - makima/frontend/src/main.tsx | 9 - makima/frontend/src/routes/daemon.tsx | 746 ---------------------------- 5 files changed, 42 insertions(+), 849 deletions(-) delete mode 100644 makima/frontend/src/routes/daemon.tsx diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 42d4241..fbf5e13 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -93,12 +93,19 @@ jobs: name: makima-${{ github.ref_name }}-linux-arm64 path: daemon-binaries + - name: Download macOS ARM64 artifact + uses: actions/download-artifact@v4 + with: + name: makima-${{ github.ref_name }}-macos-arm64 + path: daemon-binaries + - name: Extract and repackage daemon binaries run: | - mkdir -p daemon-extracted/linux-x86_64 daemon-extracted/linux-arm64 + mkdir -p daemon-extracted/linux-x86_64 daemon-extracted/linux-arm64 daemon-extracted/macos-arm64 tar xzf daemon-binaries/makima-${{ github.ref_name }}-linux-x86_64.tar.gz -C daemon-extracted/linux-x86_64 tar xzf daemon-binaries/makima-${{ github.ref_name }}-linux-arm64.tar.gz -C daemon-extracted/linux-arm64 + tar xzf daemon-binaries/makima-${{ github.ref_name }}-macos-arm64.tar.gz -C daemon-extracted/macos-arm64 tar czvf daemon-binaries.tar.gz -C daemon-extracted . @@ -150,24 +157,27 @@ jobs: ```bash # Linux x86_64 - curl -LO https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/makima-${{ github.ref_name }}-linux-x86_64.tar.gz - tar xzf makima-${{ github.ref_name }}-linux-x86_64.tar.gz + curl -fsSL https://api.makima.jp/api/v1/daemon/download/linux-x86_64 -o makima + chmod +x makima sudo mv makima /usr/local/bin/ # Linux ARM64 - curl -LO https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/makima-${{ github.ref_name }}-linux-arm64.tar.gz - tar xzf makima-${{ github.ref_name }}-linux-arm64.tar.gz + curl -fsSL https://api.makima.jp/api/v1/daemon/download/linux-arm64 -o makima + chmod +x makima sudo mv makima /usr/local/bin/ # macOS Intel - curl -LO https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/makima-${{ github.ref_name }}-macos-x86_64.tar.gz - tar xzf makima-${{ github.ref_name }}-macos-x86_64.tar.gz + curl -fsSL https://api.makima.jp/api/v1/daemon/download/macos-x86_64 -o makima + chmod +x makima sudo mv makima /usr/local/bin/ # macOS Apple Silicon - curl -LO https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/makima-${{ github.ref_name }}-macos-arm64.tar.gz - tar xzf makima-${{ github.ref_name }}-macos-arm64.tar.gz + curl -fsSL https://api.makima.jp/api/v1/daemon/download/macos-arm64 -o makima + chmod +x makima sudo mv makima /usr/local/bin/ + + # Or use the install script (auto-detects platform): + curl -fsSL https://raw.githubusercontent.com/soryu-co/soryu/master/install.sh | bash ``` ### Verification @@ -202,24 +212,27 @@ jobs: ```bash # Linux x86_64 - curl -LO https://github.com/soryu-co/makima/releases/download/${{ github.ref_name }}/makima-${{ github.ref_name }}-linux-x86_64.tar.gz - tar xzf makima-${{ github.ref_name }}-linux-x86_64.tar.gz + curl -fsSL https://api.makima.jp/api/v1/daemon/download/linux-x86_64 -o makima + chmod +x makima sudo mv makima /usr/local/bin/ # Linux ARM64 - curl -LO https://github.com/soryu-co/makima/releases/download/${{ github.ref_name }}/makima-${{ github.ref_name }}-linux-arm64.tar.gz - tar xzf makima-${{ github.ref_name }}-linux-arm64.tar.gz + curl -fsSL https://api.makima.jp/api/v1/daemon/download/linux-arm64 -o makima + chmod +x makima sudo mv makima /usr/local/bin/ # macOS Intel - curl -LO https://github.com/soryu-co/makima/releases/download/${{ github.ref_name }}/makima-${{ github.ref_name }}-macos-x86_64.tar.gz - tar xzf makima-${{ github.ref_name }}-macos-x86_64.tar.gz + curl -fsSL https://api.makima.jp/api/v1/daemon/download/macos-x86_64 -o makima + chmod +x makima sudo mv makima /usr/local/bin/ # macOS Apple Silicon - curl -LO https://github.com/soryu-co/makima/releases/download/${{ github.ref_name }}/makima-${{ github.ref_name }}-macos-arm64.tar.gz - tar xzf makima-${{ github.ref_name }}-macos-arm64.tar.gz + curl -fsSL https://api.makima.jp/api/v1/daemon/download/macos-arm64 -o makima + chmod +x makima sudo mv makima /usr/local/bin/ + + # Or use the install script (auto-detects platform): + curl -fsSL https://raw.githubusercontent.com/soryu-co/soryu/master/install.sh | bash ``` ### Verification diff --git a/install.sh b/install.sh index b7a96fe..3dc76e1 100644 --- a/install.sh +++ b/install.sh @@ -5,7 +5,6 @@ set -e # Usage: curl -fsSL https://raw.githubusercontent.com/soryu-co/soryu/master/install.sh | bash # curl -fsSL https://raw.githubusercontent.com/soryu-co/soryu/master/install.sh | INSTALL_DIR=/opt/bin bash -REPO="soryu-co/soryu" INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}" BINARY_NAME="makima" @@ -39,10 +38,6 @@ check_dependencies() { missing="$missing curl" fi - if ! command -v tar &> /dev/null; then - missing="$missing tar" - fi - if [ -n "$missing" ]; then print_error "Missing required tools:$missing" print_info "Please install the missing tools and try again." @@ -90,29 +85,11 @@ detect_arch() { esac } -# Get the latest release version from GitHub API -get_latest_version() { - local version - version=$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') - - if [ -z "$version" ]; then - print_error "Failed to fetch latest release version from GitHub" - exit 1 - fi - - echo "$version" -} - -# Construct the download URL for the release asset +# Construct the download URL for the binary get_download_url() { - local version=$1 - local os=$2 - local arch=$3 - - # Handle macOS arm64 vs Linux x86_64 naming - local asset_name="makima-${version}-${os}-${arch}.tar.gz" - - echo "https://github.com/$REPO/releases/download/${version}/${asset_name}" + local os=$1 + local arch=$2 + echo "https://api.makima.jp/api/v1/daemon/download/${os}-${arch}" } # Download and install the binary @@ -120,55 +97,26 @@ install_binary() { local url=$1 local tmpdir tmpdir=$(mktemp -d) - local tarball="$tmpdir/makima.tar.gz" + local binary="$tmpdir/$BINARY_NAME" print_info "Downloading from: $url" - # Download the tarball - if ! curl -fsSL "$url" -o "$tarball"; then - print_error "Failed to download release from: $url" - print_info "Please check if the release exists for your platform." + if ! curl -fsSL "$url" -o "$binary"; then + print_error "Failed to download from: $url" + print_info "Please check if the binary is available for your platform." rm -rf "$tmpdir" exit 1 fi - # Verify download was successful - if [ ! -f "$tarball" ] || [ ! -s "$tarball" ]; then + if [ ! -f "$binary" ] || [ ! -s "$binary" ]; then print_error "Downloaded file is empty or missing" rm -rf "$tmpdir" exit 1 fi - # Extract the tarball - print_info "Extracting archive..." - if ! tar -xzf "$tarball" -C "$tmpdir"; then - print_error "Failed to extract archive" - rm -rf "$tmpdir" - exit 1 - fi - - # Find the binary (it should be in the extracted files) - local binary - if [ -f "$tmpdir/$BINARY_NAME" ]; then - binary="$tmpdir/$BINARY_NAME" - elif [ -f "$tmpdir/makima/$BINARY_NAME" ]; then - binary="$tmpdir/makima/$BINARY_NAME" - else - # Search for the binary - binary=$(find "$tmpdir" -name "$BINARY_NAME" -type f | head -1) - if [ -z "$binary" ]; then - print_error "Could not find $BINARY_NAME binary in archive" - print_info "Archive contents:" - ls -la "$tmpdir" - rm -rf "$tmpdir" - exit 1 - fi - fi - - # Make binary executable chmod +x "$binary" - # Create install directory if it doesn't exist + # Create install directory if needed if [ ! -d "$INSTALL_DIR" ]; then print_info "Creating directory: $INSTALL_DIR" if ! mkdir -p "$INSTALL_DIR" 2>/dev/null; then @@ -177,14 +125,13 @@ install_binary() { fi fi - # Install binary + # Install print_info "Installing to: $INSTALL_DIR/$BINARY_NAME" if ! mv "$binary" "$INSTALL_DIR/$BINARY_NAME" 2>/dev/null; then print_warning "Cannot write to $INSTALL_DIR, trying with sudo..." sudo mv "$binary" "$INSTALL_DIR/$BINARY_NAME" fi - # Cleanup rm -rf "$tmpdir" } @@ -217,30 +164,19 @@ main() { print_info "====================" print_info "" - # Check dependencies check_dependencies - # Detect platform local os arch os=$(detect_os) arch=$(detect_arch) print_info "Detected platform: $os-$arch" - # Get latest version - print_info "Fetching latest release..." - local version - version=$(get_latest_version) - print_info "Latest version: $version" - - # Construct download URL local url - url=$(get_download_url "$version" "$os" "$arch") + url=$(get_download_url "$os" "$arch") - # Download and install print_info "" install_binary "$url" - # Verify print_info "" verify_installation diff --git a/makima/frontend/src/components/NavStrip.tsx b/makima/frontend/src/components/NavStrip.tsx index 1bd0891..9556458 100644 --- a/makima/frontend/src/components/NavStrip.tsx +++ b/makima/frontend/src/components/NavStrip.tsx @@ -17,7 +17,6 @@ const NAV_LINKS: NavLink[] = [ { label: "Mesh", href: "/mesh", requiresAuth: true }, { label: "Daemons", href: "/daemons", requiresAuth: true }, { label: "History", href: "/history", requiresAuth: true }, - { label: "Daemon", href: "/daemon", requiresAuth: true }, ]; export function NavStrip() { diff --git a/makima/frontend/src/main.tsx b/makima/frontend/src/main.tsx index a75d6a0..32c05ba 100644 --- a/makima/frontend/src/main.tsx +++ b/makima/frontend/src/main.tsx @@ -21,7 +21,6 @@ import SettingsPage from "./routes/settings"; import ContractFilePage from "./routes/contract-file"; import SpeakPage from "./routes/speak"; import DirectivesPage from "./routes/directives"; -import DaemonPage from "./routes/daemon"; createRoot(document.getElementById("root")!).render( @@ -162,14 +161,6 @@ createRoot(document.getElementById("root")!).render( } /> - - - - } - /> - {children} - - ); -} - -function ErrorAlert({ children }: { children: React.ReactNode }) { - return ( -
- {children} -
- ); -} - -function CodeBlock({ children }: { children: React.ReactNode }) { - return ( - - {children} - - ); -} - -function StepNumber({ n }: { n: number }) { - return ( - - {n} - - ); -} - -// ============================================================================= -// Download Section -// ============================================================================= - -function DownloadSection() { - const [release, setRelease] = useState(null); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [userPlatform] = useState(detectPlatform); - - useEffect(() => { - const fetchRelease = async () => { - try { - setLoading(true); - setError(null); - const res = await fetch( - "https://api.github.com/repos/soryu-co/makima/releases/latest" - ); - if (!res.ok) { - throw new Error(`GitHub API returned ${res.status}`); - } - const data: GitHubRelease = await res.json(); - setRelease(data); - } catch (err) { - setError( - err instanceof Error ? err.message : "Failed to fetch release info" - ); - } finally { - setLoading(false); - } - }; - fetchRelease(); - }, []); - - const platforms: PlatformDownload[] = [ - { - label: "Linux x86_64", - arch: "linux-x86_64", - pattern: "linux-x86_64.tar.gz", - asset: null, - recommended: userPlatform === "linux-x86_64", - }, - { - label: "macOS Intel (x86_64)", - arch: "macos-x86_64", - pattern: "macos-x86_64.tar.gz", - asset: null, - recommended: userPlatform === "macos-x86_64", - }, - { - label: "macOS Apple Silicon (ARM64)", - arch: "macos-arm64", - pattern: "macos-arm64.tar.gz", - asset: null, - recommended: userPlatform === "macos-arm64", - }, - ]; - - // Match assets to platforms - if (release) { - for (const p of platforms) { - p.asset = - release.assets.find((a) => a.name.includes(p.pattern)) || null; - } - } - - // Sort recommended first - const sortedPlatforms = [...platforms].sort( - (a, b) => (b.recommended ? 1 : 0) - (a.recommended ? 1 : 0) - ); - - return ( -
- Download Daemon - - {loading && ( -

- Fetching latest release... -

- )} - - {error && Failed to load release: {error}} - - {release && ( - <> -
-
- - {release.tag_name} - - - {formatDate(release.published_at)} - -
- - All Releases → - -
- -
- {sortedPlatforms.map((p) => ( -
-
- - {p.label} - - {p.recommended && ( - - Detected - - )} - {p.asset && ( - - {formatBytes(p.asset.size)} - - )} -
- {p.asset ? ( - - Download - - ) : ( - - Not available - - )} -
- ))} -
- - )} -
- ); -} - -// ============================================================================= -// Setup Instructions Section -// ============================================================================= - -function SetupSection() { - const [showConfig, setShowConfig] = useState(false); - - return ( -
- Setup Instructions -
-
- -
-

- Download the binary for your platform above -

-
-
- -
- -
-

- Extract the archive -

- tar xzf makima-*.tar.gz -
-
- -
- -
-

- Move to PATH -

- sudo mv makima /usr/local/bin/ -
-
- -
- -
-

- Set your API key ( - - generate one in Settings - - ) -

- export MAKIMA_API_KEY="your-key" -
-
- -
- -
-

- Set server URL -

- - export MAKIMA_DAEMON_SERVER_URL="ws://your-server:8080" - -
-
- -
- -
-

- Run the daemon -

- makima daemon -
-
-
- - {/* Config file alternative */} -
- - {showConfig && ( -
-

- Create makima-daemon.toml{" "} - in the working directory: -

- - {`[daemon] -api_key = "your-key" -server_url = "ws://your-server:8080" -max_concurrent_tasks = 4`} - -
- )} -
-
- ); -} - -// ============================================================================= -// Cloudflare Edge Deployment Section -// ============================================================================= - -function CloudflareAgentSection() { - const [showSetup, setShowSetup] = useState(false); - - const benefits = [ - { - label: "Global edge presence", - desc: "Lower latency from 300+ Cloudflare locations worldwide", - }, - { - label: "Auto-scaling & hibernation", - desc: "Cost-efficient — only runs when needed", - }, - { - label: "WebSocket relay", - desc: "Coordinate remote daemon instances through persistent connections", - }, - { - label: "Durable Objects", - desc: "Built on Cloudflare's stateful edge compute primitives", - }, - ]; - - return ( -
- Edge Deployment - -

- Deploy a lightweight Makima relay agent on Cloudflare's edge network for - global, low-latency daemon coordination. Ideal for distributed teams or - production deployments requiring high availability. -

- - {/* Benefits */} -
- {benefits.map((b) => ( -
- -
- {b.label} - — {b.desc} -
-
- ))} -
- - {/* Quick Setup */} -
- - {showSetup && ( -
-
- -
-

- Navigate to the Cloudflare agent directory -

- cd makima/cloudflare-agent -
-
-
- -
-

- Run the setup script -

- ./setup.sh -
-
-
- -
-

- Deploy to Cloudflare -

- npx wrangler deploy -
-
-
- )} -
- - {/* Link to repo */} -
- - Full documentation & source - - - View on GitHub → - -
-
- ); -} - -// ============================================================================= -// Connected Daemons Section -// ============================================================================= - -function ConnectedDaemonsSection() { - const [daemons, setDaemons] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [restartingDaemonId, setRestartingDaemonId] = useState( - null - ); - const [restartConfirmDaemonId, setRestartConfirmDaemonId] = useState< - string | null - >(null); - - const loadDaemons = useCallback(async () => { - try { - setError(null); - const response = await listDaemons(); - setDaemons(response.daemons); - } catch (err) { - setError( - err instanceof Error ? err.message : "Failed to load daemons" - ); - } finally { - setLoading(false); - } - }, []); - - useEffect(() => { - loadDaemons(); - }, [loadDaemons]); - - // Auto-refresh every 30 seconds - useEffect(() => { - const interval = setInterval(() => { - loadDaemons(); - }, 30000); - return () => clearInterval(interval); - }, [loadDaemons]); - - const handleRestartDaemon = async (id: string) => { - try { - setRestartingDaemonId(id); - setError(null); - await restartDaemon(id); - setRestartConfirmDaemonId(null); - // Daemon will restart, so refresh the list after a short delay - setTimeout(() => { - loadDaemons(); - }, 2000); - } catch (err) { - setError( - err instanceof Error ? err.message : "Failed to restart daemon" - ); - } finally { - setRestartingDaemonId(null); - } - }; - - return ( -
-
-
-

- Connected Daemons -

- {daemons.length > 0 && ( - - ({daemons.filter((d) => d.status === "connected").length}{" "} - connected / {daemons.length} total) - - )} -
- -
- - {error && {error}} - - {loading && daemons.length === 0 ? ( -

Loading...

- ) : daemons.length === 0 ? ( -
-

- No daemons connected -

-

- Follow the setup instructions above to connect a daemon -

-
- ) : ( -
- {daemons.map((daemon) => ( -
-
- - {daemon.hostname || "Unknown Host"} - -
- - {daemon.status} - -
-
-
-
- Tasks - - {daemon.currentTaskCount} / {daemon.maxConcurrentTasks} - -
-
- Connected - - {new Date(daemon.connectedAt).toLocaleString()} - -
- {daemon.machineId && ( -
- Machine - - {daemon.machineId.substring(0, 16)}... - -
- )} -
- {/* Restart Section */} - {daemon.status === "connected" && ( -
- {restartConfirmDaemonId === daemon.id ? ( -
- - Restart daemon? Running tasks will be interrupted. - -
- - -
-
- ) : ( - - )} -
- )} -
- ))} -
- )} -
- ); -} - -// ============================================================================= -// Main Page -// ============================================================================= - -export default function DaemonPage() { - const { - isAuthenticated, - isAuthConfigured, - isLoading: authLoading, - } = useAuth(); - const navigate = useNavigate(); - - useEffect(() => { - if (!authLoading && isAuthConfigured && !isAuthenticated) { - navigate("/login"); - } - }, [authLoading, isAuthConfigured, isAuthenticated, navigate]); - - if (authLoading) { - return ( -
- -
-

Loading...

-
-
- ); - } - - return ( -
- -
- {/* Page header */} -
-

- Daemon Management -

-

- Download, configure, and monitor Makima daemons -

-
- -
- {/* Left Column: Downloads & Setup */} -
- - -
- - {/* Right Column: Edge Deployment & Connected Daemons */} -
- - -
-
-
-
- ); -} -- cgit v1.2.3