diff --git a/README.md b/README.md index 772ac40..6591086 100644 --- a/README.md +++ b/README.md @@ -25,14 +25,14 @@ Start exploring the Sovereign Agent Mesh: ### For Users & Operators Get a node running on the public testnet (`bananas.sam-mesh.dev`) in minutes: - ๐Ÿš€ **[User Quick Start Guide](site/content/docs/quickstart.md)**: Connect and run a SAM node using binaries or Docker, and query the local MCP server. -- ๐Ÿค– **[Agent Integration Guides](site/content/docs/agent_integration.md)**: Connect Google Gemini, Claude, and other AI agents to your SAM node to dynamically discover and call tools across the mesh. +- ๐Ÿค– **[Agent Integration Guides](site/content/docs/integrations/_index.md)**: Connect Google Gemini, Claude, and other AI agents to your SAM node to dynamically discover and call tools across the mesh. - ๐Ÿ“– **[CLI Reference](site/content/docs/cli/reference.md)**: Comprehensive CLI reference and configurations. -- ๐Ÿ“ก **[Testnet Validation Tutorial](site/content/docs/testnet-validation.md)**: Real-time verification, remote tool invocation, and HTTP stream proxies. +- ๐Ÿ“ก **[Testnet Validation Tutorial](site/content/docs/development/testnet-validation.md)**: Real-time verification, remote tool invocation, and HTTP stream proxies. ### For Developers & Contributors Compile from source, run local clusters, or execute tests: -- ๐Ÿ› ๏ธ **[Developer Guide](site/content/docs/development.md)**: Prereqs, compilation, local hub setup, and Kubernetes Kind deployment. -- ๐Ÿงช **[Testing Guide](site/content/docs/testing.md)**: Go tests, E2E BATS, and containerized mesh execution. +- ๐Ÿ› ๏ธ **[Developer Guide](site/content/docs/development/_index.md)**: Prereqs, compilation, local hub setup, and Kubernetes Kind deployment. +- ๐Ÿงช **[Testing Guide](site/content/docs/development/testing.md)**: Go tests, E2E BATS, and containerized mesh execution. --- diff --git a/site/assets/icons/logo.svg b/site/assets/icons/logo.svg new file mode 100644 index 0000000..725b335 --- /dev/null +++ b/site/assets/icons/logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/site/assets/scss/_styles_project.scss b/site/assets/scss/_styles_project.scss index 8ebcf66..bea189b 100644 --- a/site/assets/scss/_styles_project.scss +++ b/site/assets/scss/_styles_project.scss @@ -1,28 +1,654 @@ -.td-navbar { - border-bottom: 2px solid $primary-light; -} +// Navbar override for documentation pages when dark mode is enabled +[data-bs-theme="dark"] { + .td-navbar { + background-color: #040911 !important; + border-bottom: 2px solid $primary-light !important; + + .nav-link { + color: #94a3b8 !important; + transition: all 0.2s ease; + + &:hover { + color: $primary-light !important; + } -// Homepage cover block with SAM logo background -.td-cover-block { - background-color: #ffffff !important; - background-image: url('/sam_logo.png') !important; - background-repeat: no-repeat !important; - background-position: center 30% !important; // Pushes image slightly higher to leave room for buttons - background-size: contain !important; - - // Set minimum height to display the logo nicely - min-height: 75vh !important; - - // Layout to push buttons to the bottom - display: flex !important; - flex-direction: column !important; - justify-content: flex-end !important; - padding-bottom: 4rem !important; + &.active { + color: $primary-light !important; + font-weight: 600; + } + } + } } -// Remove the default dark overlay shadow on the cover block -.td-overlay::before { - background: transparent !important; - opacity: 0 !important; +// --- Custom Landing Page --- +.sam-landing-page { + background-color: #040911; // Dark slate/navy space color + color: #f8fafc; + min-height: 100vh; + margin: 0; + padding: 0; + display: flex; + justify-content: center; + align-items: center; + position: relative; + overflow: hidden; + font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + + // Ambient mesh network grid background + .mesh-grid { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: + linear-gradient(rgba(0, 240, 255, 0.04) 1px, transparent 1px), + linear-gradient(90deg, rgba(0, 240, 255, 0.04) 1px, transparent 1px); + background-size: 60px 60px; + background-position: center; + mask-image: radial-gradient(circle at center, black 30%, transparent 80%); + -webkit-mask-image: radial-gradient(circle at center, black 30%, transparent 80%); + z-index: 1; + } + + // Soft glowing orbs in background to represent network nodes or hubs + .mesh-glow-cyan { + position: absolute; + width: 600px; + height: 600px; + background: radial-gradient(circle, rgba(0, 240, 255, 0.08) 0%, rgba(0, 240, 255, 0) 70%); + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 2; + pointer-events: none; + animation: pulseGlow 10s ease-in-out infinite alternate; + } + + .mesh-glow-yellow { + position: absolute; + width: 400px; + height: 400px; + background: radial-gradient(circle, rgba(246, 195, 68, 0.05) 0%, rgba(246, 195, 68, 0) 70%); + top: 40%; + left: 35%; + z-index: 2; + pointer-events: none; + animation: floatGlow 12s ease-in-out infinite alternate; + } + + // Main container (Split Layout) + .landing-container { + position: relative; + z-index: 10; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + gap: 5rem; + padding: 3rem; + max-width: 1200px; + width: 100%; + + @media (max-width: 991px) { + flex-direction: column; + gap: 3rem; + padding: 2rem; + text-align: center; + } + } + + // Hero Brand Column + .hero-brand-col { + flex: 1; + display: flex; + flex-direction: column; + align-items: flex-start; + + @media (max-width: 991px) { + align-items: center; + } + } + + // Hero Terminal Column + .hero-terminal-col { + flex: 1.1; + display: flex; + justify-content: center; + width: 100%; + animation: floatHero 8s ease-in-out infinite alternate; + } + + // Hero Logo styling + .logo-container { + position: relative; + margin-bottom: 2rem; + display: inline-block; + + .sam-hero-logo { + width: 200px; + height: auto; + display: block; + position: relative; + z-index: 5; + filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.5)); + } + + // Behind logo glow + .logo-backdrop-glow { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 180px; + height: 180px; + background: radial-gradient(circle, rgba(0, 240, 255, 0.25) 0%, rgba(246, 195, 68, 0.1) 50%, rgba(0, 0, 0, 0) 70%); + filter: blur(15px); + z-index: 1; + border-radius: 50%; + animation: pulseLogoGlow 4s ease-in-out infinite alternate; + } + } + + // Typography + .landing-title { + font-size: 3.5rem; + font-weight: 800; + letter-spacing: 0.25em; + margin: 0; + text-transform: uppercase; + background: linear-gradient(135deg, #ffffff 30%, #a5f3fc 100%); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + text-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + line-height: 1.1; + margin-left: 0.25em; // Offset to center letter-spacing + + @media (max-width: 576px) { + font-size: 2.8rem; + } + } + + .landing-subtitle { + font-size: 0.95rem; + font-weight: 700; + color: $primary-light; // Cyber cyan + letter-spacing: 0.4em; + text-transform: uppercase; + margin-top: 0.75rem; + margin-bottom: 1.5rem; + margin-left: 0.4em; // Offset to center letter-spacing + text-shadow: 0 0 10px rgba(0, 240, 255, 0.3); + } + + .landing-description { + font-size: 1.1rem; + line-height: 1.7; + color: #94a3b8; // Slate-400 + margin-bottom: 2.5rem; + max-width: 500px; + text-align: left; + + @media (max-width: 991px) { + text-align: center; + } + } + + // Action Buttons + .landing-actions { + display: flex; + gap: 1.5rem; + justify-content: flex-start; + width: 100%; + + @media (max-width: 991px) { + justify-content: center; + } + + @media (max-width: 480px) { + flex-direction: column; + gap: 1rem; + align-items: stretch; + } + } + + .btn-sleek { + display: inline-block; + padding: 0.9rem 2.2rem; + font-size: 1rem; + font-weight: 600; + letter-spacing: 0.05em; + text-decoration: none !important; + border-radius: 8px; + transition: all 0.3s cubic-bezier(0.2, 0.8, 0.2, 1); + text-align: center; + position: relative; + overflow: hidden; + + &.btn-cyan { + border: 1px solid rgba(0, 240, 255, 0.6); + color: #00f0ff; + background: rgba(0, 240, 255, 0.03); + box-shadow: 0 0 20px rgba(0, 240, 255, 0.05); + + &:hover { + background: #00f0ff; + color: #040911; + box-shadow: 0 0 25px rgba(0, 240, 255, 0.4); + transform: translateY(-2px); + } + + &:active { + transform: translateY(0); + } + } + + &.btn-dark { + border: 1px solid rgba(255, 255, 255, 0.1); + color: #e2e8f0; + background: rgba(255, 255, 255, 0.02); + + &:hover { + background: rgba(255, 255, 255, 0.08); + border-color: rgba(255, 255, 255, 0.3); + color: #ffffff; + transform: translateY(-2px); + } + + &:active { + transform: translateY(0); + } + } + } + + // Terminal Window Styling + .terminal-window { + background: rgba(7, 19, 30, 0.6); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border: 1px solid rgba(0, 240, 255, 0.15); + border-radius: 10px; + width: 100%; + max-width: 650px; + box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5), 0 0 30px rgba(0, 240, 255, 0.05); + font-family: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace; + overflow: hidden; + } + + .terminal-header { + background: rgba(4, 9, 17, 0.85); + border-bottom: 1px solid rgba(255, 255, 255, 0.05); + padding: 0.75rem 1.25rem; + display: flex; + justify-content: space-between; + align-items: center; + } + + .terminal-buttons { + display: flex; + gap: 0.5rem; + + .btn-circle { + width: 10px; + height: 10px; + border-radius: 50%; + display: inline-block; + + &.btn-red { + background-color: #ef4444; + } + + &.btn-yellow { + background-color: #f59e0b; + } + + &.btn-green { + background-color: #10b981; + } + } + } + + .terminal-title { + color: #64748b; + font-size: 0.75rem; + letter-spacing: 0.05em; + } + + .terminal-body { + padding: 1.25rem; + font-size: 0.85rem; + line-height: 1.6; + text-align: left; + } + + .terminal-line { + margin-bottom: 0.5rem; + + &:last-child { + margin-bottom: 0; + } + } + + .t-prompt { + color: $primary-light; // Cyber cyan + font-weight: bold; + user-select: none; + } + + .t-cmd { + color: #ffffff; + font-weight: 500; + } + + .t-output { + color: #94a3b8; // Slate-400 + } + + .t-success { + color: $yellow; // Banana yellow + font-weight: 500; + } + + // Animation definitions + @keyframes floatHero { + 0% { + transform: translateY(0px); + } + + 100% { + transform: translateY(-12px); + } + } + + @keyframes pulseLogoGlow { + 0% { + opacity: 0.8; + transform: translate(-50%, -50%) scale(0.95); + } + + 100% { + opacity: 1.2; + transform: translate(-50%, -50%) scale(1.05); + } + } + + @keyframes pulseGlow { + 0% { + transform: translate(-50%, -50%) scale(0.9); + opacity: 0.7; + } + + 100% { + transform: translate(-50%, -50%) scale(1.1); + opacity: 1.1; + } + } + + @keyframes floatGlow { + 0% { + transform: translateY(0px) translateX(0px); + } + + 50% { + transform: translateY(-20px) translateX(15px); + } + + 100% { + transform: translateY(0px) translateX(0px); + } + } } +// --- Custom Documentation Dark Theme --- +[data-bs-theme="dark"] { + + body.td-page, + body.td-section { + background-color: #050b14; + color: #e2e8f0; + + // Set the main layout container backgrounds + .td-outer, + .td-main, + .td-sidebar, + .td-sidebar-toc { + background-color: #050b14 !important; + color: #e2e8f0 !important; + } + + // Sidebar link overrides + .td-sidebar { + border-right: 1px solid rgba(255, 255, 255, 0.05); + + .td-sidebar-link { + color: #94a3b8 !important; + transition: all 0.2s ease; + + &:hover { + color: $primary-light !important; + text-shadow: 0 0 8px rgba(0, 240, 255, 0.3); + } + + &.active, + &.td-sidebar-nav-active-item { + color: $primary-light !important; + font-weight: 600; + + &::before { + background-color: $primary-light !important; + box-shadow: 0 0 10px rgba(0, 240, 255, 0.5); + } + } + } + + // Active item text highlighting + .td-sidebar-nav-active-item { + color: $primary-light !important; + } + } + + // Left sidebar menu tree active node custom styles + .td-sidebar-nav .active { + color: $primary-light !important; + } + + // Table of Contents styling + .td-sidebar-toc { + border-left: 1px solid rgba(255, 255, 255, 0.05); + + a { + color: #94a3b8 !important; + font-size: 0.85rem; + transition: all 0.2s ease; + + &:hover { + color: $primary-light !important; + text-decoration: none; + } + } + + .active-toc-item { + color: $primary-light !important; + font-weight: 600; + } + } + + // Navigation Breadcrumbs + .td-breadcrumbs { + .breadcrumb-item { + color: #64748b; + + a { + color: #94a3b8; + + &:hover { + color: $primary-light; + } + } + + &.active { + color: #e2e8f0; + } + } + } + + // Main Content Styles + .td-content { + color: #cbd5e1; + + h1 { + color: #ffffff; + font-weight: 800; + letter-spacing: -0.02em; + border-bottom: 1px solid rgba(0, 240, 255, 0.15); + padding-bottom: 0.75rem; + margin-bottom: 2rem; + } + + h2 { + color: $primary-light; + font-weight: 700; + letter-spacing: -0.01em; + margin-top: 3rem; + margin-bottom: 1.25rem; + border-bottom: 1px solid rgba(255, 255, 255, 0.05); + padding-bottom: 0.5rem; + } + + h3 { + color: #ffffff; + font-weight: 600; + margin-top: 2.5rem; + margin-bottom: 1rem; + } + + h4, + h5, + h6 { + color: #ffffff; + font-weight: 600; + } + + // Code Blocks (Syntax Highlighting wrappers) + pre { + background-color: #0b1928 !important; + border: 1px solid rgba(0, 240, 255, 0.15) !important; + border-radius: 8px !important; + padding: 1.2rem !important; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); + + code { + background-color: transparent !important; + border: none !important; + padding: 0 !important; + color: #e2e8f0 !important; + } + } + + // Inline Code + code { + background-color: #0b1928 !important; + color: $yellow !important; + border: 1px solid rgba(255, 255, 255, 0.05) !important; + padding: 0.2rem 0.4rem !important; + border-radius: 4px !important; + font-size: 0.9em; + } + + // Hyperlinks + a:not(.btn) { + color: $primary-light; + text-decoration: none; + transition: all 0.2s ease; + border-bottom: 1px solid rgba(0, 240, 255, 0.2); + + &:hover { + color: $yellow; + border-bottom-color: rgba(246, 195, 68, 0.4); + text-shadow: 0 0 8px rgba(246, 195, 68, 0.15); + } + } + + // Tables + table { + width: 100%; + border-collapse: collapse; + margin: 2rem 0; + + th { + background-color: rgba(0, 240, 255, 0.03); + border-bottom: 2px solid rgba(0, 240, 255, 0.15); + color: #ffffff; + font-weight: 600; + padding: 0.75rem 1rem; + text-align: left; + } + + td { + border-bottom: 1px solid rgba(255, 255, 255, 0.05); + padding: 0.75rem 1rem; + } + + tr:hover { + background-color: rgba(255, 255, 255, 0.01); + } + } + + // Custom alerts styling + .alert { + border-radius: 8px; + padding: 1.25rem; + margin: 2rem 0; + color: #e2e8f0; + + h4 { + color: #ffffff; + margin-top: 0; + } + + a { + color: #ffffff !important; + font-weight: 600; + text-decoration: underline !important; + } + } + + .alert-primary, + .alert-info, + .alert-notice { + background-color: rgba(0, 240, 255, 0.04) !important; + border: 1px solid rgba(0, 240, 255, 0.1) !important; + border-left: 4px solid $primary-light !important; + } + + .alert-warning { + background-color: rgba(246, 195, 68, 0.04) !important; + border: 1px solid rgba(246, 195, 68, 0.1) !important; + border-left: 4px solid $yellow !important; + } + + .alert-danger { + background-color: rgba(239, 68, 68, 0.04) !important; + border: 1px solid rgba(239, 68, 68, 0.1) !important; + border-left: 4px solid #ef4444 !important; + } + } + + // Footer styling + .td-footer { + background-color: #040911 !important; + border-top: 1px solid rgba(255, 255, 255, 0.05) !important; + color: #64748b !important; + padding: 3rem 0; + + a { + color: #94a3b8; + + &:hover { + color: $primary-light; + } + } + } + } +} \ No newline at end of file diff --git a/site/content/_index.md b/site/content/_index.md index 830fd9d..f0788c9 100644 --- a/site/content/_index.md +++ b/site/content/_index.md @@ -1,10 +1,5 @@ --- title: SAM +description: Sovereign Agent Mesh - A zero-config, zero-trust decentralized mesh network built for autonomous AI agents. --- -{{< blocks/cover title="" image_anchor="top" height="full" >}} -
- Read the Docs - GitHub Project -
-{{< /blocks/cover >}} diff --git a/site/content/docs/_index.md b/site/content/docs/_index.md index d3928c8..aa6dc08 100644 --- a/site/content/docs/_index.md +++ b/site/content/docs/_index.md @@ -1,5 +1,7 @@ -# SAM Documentation - +--- +title: "SAM Documentation" +linkTitle: "Documentation" +--- This repository currently provides a minimal SAM runtime with two binaries: - `sam-hub`: OIDC bridge and identity biscuit issuer @@ -20,10 +22,12 @@ The documentation here is intentionally small and aligned with what is implement ## Start Here - [Quick Start](quickstart.md) - User Quick Start using Docker. +- [Hub Configuration](user/hub-configuration.md) - OIDC authentication, key rings, and custom policy rules in `policies.yaml`. +- [Agent Usage](user/agent-usage.md) - Node authorization flows, MCP endpoints, and how agents connect. - [CLI Reference](cli/reference.md) - CLI command usage reference. -- [Developer Guide](development.md) - Building from source, local testing, and Kind setups. -- [Testing Guide](testing.md) - Detailed test layer and troubleshooting information. -- [Testnet Validation Tutorial](testnet-validation.md) - Real-time integration and MCP verification with public testnets. +- [Developer Guide](development/_index.md) - Building from source, local testing, and Kind setups. +- [Testing Guide](development/testing.md) - Detailed test layer and troubleshooting information. +- [Testnet Validation Tutorial](development/testnet-validation.md) - Real-time integration and MCP verification with public testnets. ## Notes diff --git a/site/content/docs/cli/reference.md b/site/content/docs/cli/reference.md deleted file mode 100644 index c5169e1..0000000 --- a/site/content/docs/cli/reference.md +++ /dev/null @@ -1,88 +0,0 @@ -# CLI Reference - -The current repository exposes two CLIs: - -- `sam-node` -- `sam-hub` - -## sam-node - -```bash -sam-node --help -``` - -### sam-node join - -Join the Sovereign Agent Mesh hub and enroll the node. - -```bash -sam-node join [hub_url] [flags] -``` - -If `hub_url` is omitted, you will be prompted to join the default community testing network (`https://bananas.sam-mesh.dev`). This command initiates an interactive OIDC device login flow and stores the returned identity Biscuit token and generated keypair in the database. - -Flags: - -* `--data-dir`: Override directory for the agent store (defaults to OS user config dir). - -### sam-node run - -Start the sovereign mesh node. - -```bash -sam-node run [flags] -``` - -Flags: - -* `--data-dir`: Override directory for the agent store (defaults to OS user config dir) where identity and private keys are loaded. -* `--bind-addr`: Local TCP address for the HTTP server (MCP and Sidecar API) (default `"127.0.0.1:8080"`). -* `--listen`: libp2p Listen Addrs (default `[/ip4/0.0.0.0/udp/5001/quic-v1,/ip4/0.0.0.0/tcp/5002]`). -* `--jwt`: Pre-fetched JWT token to enroll dynamically. -* `--jwt-path`: Path to a file containing a pre-fetched JWT token. -* `--oidc-issuer`: OIDC Issuer URL for M2M auto-enrollment. -* `--client-id`: OIDC Client ID for M2M auto-enrollment. -* `--client-secret`: OIDC Client Secret for M2M auto-enrollment. -* `--api-token`: Static Bearer token for API authorization. -* `--log-level`: Log level (debug, info, warn, error) (default `"info"`). - -Examples: - -```bash -# Start using saved identity -sam-node run - -# Start with explicit OIDC details -sam-node run --oidc-issuer https://issuer.example.com --client-id my-id --client-secret my-secret - -# Start and bind HTTP API to all interfaces (e.g. inside Docker) -sam-node run --bind-addr 0.0.0.0:8080 -``` - -## sam-hub - -```bash -sam-hub --help -``` - -`sam-hub` runs the OIDC bridge, issues identity biscuits, and gates unauthenticated peers. - -Flags: - -- `--issuer`: OIDC issuer URL -- `--client-id`: OIDC client ID -- `--client-secret`: OIDC client secret -- `--key`: 32-byte hex seed used to derive Ed25519 biscuit signing key -- `--listen`: repeatable libp2p listen addresses -- `--mesh`: mesh name -- `--public-url`: public callback base URL - -Example: - -```bash -sam-hub \ - --issuer https://issuer.example.com \ - --client-id sam-client \ - --client-secret sam-secret \ - --key $(openssl rand -hex 32) -``` diff --git a/site/content/docs/development.md b/site/content/docs/development/_index.md similarity index 97% rename from site/content/docs/development.md rename to site/content/docs/development/_index.md index 1ec9f98..3a22870 100644 --- a/site/content/docs/development.md +++ b/site/content/docs/development/_index.md @@ -1,5 +1,8 @@ -# Developer Guide & Repository Setup - +--- +title: "Developer Guide" +linkTitle: "Developer Guide" +weight: 4 +--- This document is for developers who want to compile SAM from source, run a local development mesh, run the test suites, or contribute to the repository. --- diff --git a/site/content/docs/kubernetes-deployment.md b/site/content/docs/development/kubernetes-deployment.md similarity index 98% rename from site/content/docs/kubernetes-deployment.md rename to site/content/docs/development/kubernetes-deployment.md index d8c42ed..8faf0cf 100644 --- a/site/content/docs/kubernetes-deployment.md +++ b/site/content/docs/development/kubernetes-deployment.md @@ -1,5 +1,7 @@ -# Kubernetes Deployment and Local Testing Guide - +--- +title: "Kubernetes Deployment and Local Testing Guide" +linkTitle: "Kubernetes Deployment and Local Testing Guide" +--- This guide explains how to deploy the `sam-hub` in a Kubernetes cluster and how to test it locally using `kind` and `cloud-provider-kind`. This guide supports using either **Google OIDC** or a **Mock OIDC Provider** for authentication. The mock provider is recommended for quick local testing as it does not require creating external credentials. diff --git a/site/content/docs/policy.md b/site/content/docs/development/policy.md similarity index 94% rename from site/content/docs/policy.md rename to site/content/docs/development/policy.md index 856ef59..d83c3e8 100644 --- a/site/content/docs/policy.md +++ b/site/content/docs/development/policy.md @@ -1,5 +1,7 @@ -# SAM Policy & Authorization Reference - +--- +title: "SAM Policy & Authorization Reference" +linkTitle: "SAM Policy & Authorization Reference" +--- SAM uses a decentralized authorization model powered by [Biscuit](https://www.biscuitsec.org/). The `sam-hub` authenticates users via OIDC and injects **Facts** into their token based on `policies.yaml`. The `sam-node` operates offline, evaluating the token against baseline rules and optional local attenuation policies. diff --git a/site/content/docs/release-tracks.md b/site/content/docs/development/release-tracks.md similarity index 95% rename from site/content/docs/release-tracks.md rename to site/content/docs/development/release-tracks.md index 50ef5bf..895ef6a 100644 --- a/site/content/docs/release-tracks.md +++ b/site/content/docs/development/release-tracks.md @@ -1,5 +1,7 @@ -# Release Tracks, Autoupdate, and Autoscaling - +--- +title: "Release Tracks, Autoupdate, and Autoscaling" +linkTitle: "Release Tracks, Autoupdate, and Autoscaling" +--- Sovereign Agent Mesh (SAM) is deployed to public endpoints using automated environments, release tracks, and self-healing/scaling infrastructure. --- diff --git a/site/content/docs/testing.md b/site/content/docs/development/testing.md similarity index 96% rename from site/content/docs/testing.md rename to site/content/docs/development/testing.md index 3f08f60..c9c760f 100644 --- a/site/content/docs/testing.md +++ b/site/content/docs/development/testing.md @@ -1,5 +1,7 @@ -# Testing - +--- +title: "Testing" +linkTitle: "Testing" +--- Current testing is intentionally minimal and aligned with the current binaries. ## Test Layers diff --git a/site/content/docs/testnet-validation.md b/site/content/docs/development/testnet-validation.md similarity index 98% rename from site/content/docs/testnet-validation.md rename to site/content/docs/development/testnet-validation.md index 84290dc..620de7a 100644 --- a/site/content/docs/testnet-validation.md +++ b/site/content/docs/development/testnet-validation.md @@ -1,5 +1,7 @@ -# Testnet & Mesh Validation Tutorial - +--- +title: "Testnet & Mesh Validation Tutorial" +linkTitle: "Testnet & Mesh Validation Tutorial" +--- This tutorial guides you through validating your local environment integration with the public Sovereign Agent Mesh (SAM) testnets (`bananas.sam-mesh.dev` or `hub.sam-mesh.dev`). You will learn how to verify your node's connection, discover remote MCP services, and invoke remote tools. --- diff --git a/site/content/docs/agent_integration.md b/site/content/docs/integrations/_index.md similarity index 85% rename from site/content/docs/agent_integration.md rename to site/content/docs/integrations/_index.md index 9cc5290..c0c5215 100644 --- a/site/content/docs/agent_integration.md +++ b/site/content/docs/integrations/_index.md @@ -1,5 +1,8 @@ -# Agent Integration Guide - +--- +title: "Agent Integration Guide" +linkTitle: "Agent Integration Guide" +weight: 2 +--- SAM is designed to be the networking layer for autonomous AI agents. The easiest way for your agent to interact with the mesh is through the **Model Context Protocol (MCP)** exposed locally by your node. Every `sam-node` runs a local MCP server that allows agents to: @@ -12,10 +15,10 @@ Every `sam-node` runs a local MCP server that allows agents to: Explore the step-by-step guides to integrate SAM with your favorite AI Agent systems: -- [Google Gemini](integrations/gemini.md): Build an interactive client using the official `google-genai` Python SDK. -- [Claude Code](integrations/claude-code.md): Connect your local node as a remote MCP server to Claude Code. -- [Claude Desktop](integrations/claude-desktop.md): Use SAM to expose the P2P tool mesh to Claude Desktop. -- [OpenClaw](integrations/openclaw.md): Integrate your node as a remote tool bridge for OpenClaw. +- [Google Gemini](gemini.md): Build an interactive client using the official `google-genai` Python SDK. +- [Claude Code](claude-code.md): Connect your local node as a remote MCP server to Claude Code. +- [Claude Desktop](claude-desktop.md): Use SAM to expose the P2P tool mesh to Claude Desktop. +- [OpenClaw](openclaw.md): Integrate your node as a remote tool bridge for OpenClaw. ## Connecting via MCP diff --git a/site/content/docs/integrations/claude-code.md b/site/content/docs/integrations/claude-code.md index 232bdd1..c22fea1 100644 --- a/site/content/docs/integrations/claude-code.md +++ b/site/content/docs/integrations/claude-code.md @@ -1,5 +1,7 @@ -# Integrating SAM with Claude Code - +--- +title: "Integrating SAM with Claude Code" +linkTitle: "Integrating SAM with Claude Code" +--- You can connect your `sam-node` to [Claude Code](https://claude.com/claude-code) as a remote MCP server, giving Claude Code agents the ability to discover and invoke tools across the SAM mesh. ## Overview diff --git a/site/content/docs/integrations/claude-desktop.md b/site/content/docs/integrations/claude-desktop.md index 8004180..f86520d 100644 --- a/site/content/docs/integrations/claude-desktop.md +++ b/site/content/docs/integrations/claude-desktop.md @@ -1,5 +1,7 @@ -# Integrating SAM with Claude Desktop - +--- +title: "Integrating SAM with Claude Desktop" +linkTitle: "Integrating SAM with Claude Desktop" +--- You can connect your `sam-node` to the [Claude Desktop](https://claude.com/download) app as an MCP server. Unlike [Claude Code](./claude-code.md), Claude Desktop has its own configuration and does **not** read Claude Code's MCP settings. ## Overview diff --git a/site/content/docs/integrations/gemini.md b/site/content/docs/integrations/gemini.md index 105af25..bc3a764 100644 --- a/site/content/docs/integrations/gemini.md +++ b/site/content/docs/integrations/gemini.md @@ -1,5 +1,7 @@ -# Running a Gemini AI Agent on the Mesh - +--- +title: "Running a Gemini AI Agent on the Mesh" +linkTitle: "Running a Gemini AI Agent on the Mesh" +--- This tutorial demonstrates how to connect a local AI Agent powered by Google Gemini (using the official `google-genai` SDK) to your local SAM node. By exposing the SAM Model Context Protocol (MCP) server to Gemini, the agent can dynamically discover tools hosted by other peers in the mesh, describe them, and execute them to solve tasks. diff --git a/site/content/docs/integrations/openclaw.md b/site/content/docs/integrations/openclaw.md index 526ba63..8a752ba 100644 --- a/site/content/docs/integrations/openclaw.md +++ b/site/content/docs/integrations/openclaw.md @@ -1,5 +1,7 @@ -# Integrating SAM with OpenClaw - +--- +title: "Integrating SAM with OpenClaw" +linkTitle: "Integrating SAM with OpenClaw" +--- You can seamlessly integrate your `sam-node` as a remote MCP server in [OpenClaw](https://openclaw.ai), allowing your agents to dynamically discover and invoke tools across the mesh. ## Overview diff --git a/site/content/docs/quickstart.md b/site/content/docs/quickstart.md index 0705af7..128344e 100644 --- a/site/content/docs/quickstart.md +++ b/site/content/docs/quickstart.md @@ -1,3 +1,9 @@ +--- +title: "Quick Start" +linkTitle: "Quick Start" +weight: 1 +--- + # Quick Start This guide gets you up and running with a SAM node connected to the public `bananas.sam-mesh.dev` mesh. You can run SAM either directly via a binary or using Docker. @@ -7,7 +13,7 @@ This guide gets you up and running with a SAM node connected to the public `bana ### Option A: Install Script (macOS / Linux) The easiest way to install the latest binaries directly: ```bash -curl -sL https://raw.githubusercontent.com/google/sam/main/install.sh | bash +curl -sL https://sam-mesh.dev/install.sh | bash ``` ### Option B: Go Install (macOS / Linux / Windows) diff --git a/site/content/docs/user/_index.md b/site/content/docs/user/_index.md new file mode 100644 index 0000000..a6525d2 --- /dev/null +++ b/site/content/docs/user/_index.md @@ -0,0 +1,15 @@ +--- +title: "User and Operator Guides" +linkTitle: "User Guides" +weight: 3 +--- + +Welcome to the User & Operator Guides. This section provides detailed documentation on how to configure, run, and manage Sovereign Agent Mesh (SAM) clusters, hubs, and node configurations. + +### In This Section + +1. **[Hub Configuration](hub-configuration.md)** + Learn how to configure the OIDC identity bridge, set up cryptographic private keys, enforce TLS/mTLS, and write custom security role policy mappings in `policies.yaml`. + +2. **[Agent Usage & Connectivity](agent-usage.md)** + Understand how nodes connect to the mesh via OIDC login, secure credentials, run local Model Context Protocol (MCP) servers, and expose secure remote tool access to agents (like Google Gemini and Claude). diff --git a/site/content/docs/user/agent-usage.md b/site/content/docs/user/agent-usage.md new file mode 100644 index 0000000..9e1abfc --- /dev/null +++ b/site/content/docs/user/agent-usage.md @@ -0,0 +1,104 @@ +--- +title: "Agent Usage & Connectivity Guide" +linkTitle: "Agent Usage" +weight: 20 +--- + +SAM nodes (`sam-node`) act as local security gateways and tool proxies for your AI agents (such as Google Gemini, Claude Code, or Claude Desktop). This document explains how to authenticate a node to the mesh and configure your agents to use it. + +--- + +## 1. Node Lifecycle Overview + +Connecting your AI agent to the Sovereign Agent Mesh involves two phases: +```mermaid +sequenceDiagram + actor User as Developer/Operator + participant Node as sam-node (Local) + participant Hub as sam-hub (Mesh) + participant Agent as AI Agent (Gemini/Claude) + + Note over User,Hub: Phase 1: Mesh Join (OIDC Authorization) + User->>Node: sam-node join --hub + Node->>Hub: Get Hub OIDC Info + Hub-->>Node: OIDC Issuer, Client ID + Node->>User: Display Login URL & Code + User->>User: Login in Browser + Node->>Hub: Exchange Code for Biscuit Identity + Node->>Node: Persist Biscuit in Local Store + + Note over User,Agent: Phase 2: Agent Tool Invocation + User->>Node: sam-node run --api-token "secret-key" + Node->>Node: Start local MCP server on 127.0.0.1:8080 + Agent->>Node: Connect to local MCP (with Bearer "secret-key") + Agent->>Node: Call Remote P2P Tool + Node->>Hub: Verify Biscuit / Allowed Policies + Node-->>Agent: Execute tool and return result +``` + +--- + +## 2. Phase 1: Joining the Mesh (`sam-node join`) + +Before starting the node daemon, you must authorize your node and obtain a cryptographic Biscuit identity. + +### Standard Login +Run the `join` command, pointing to the mesh control hub: +```bash +sam-node join --hub https://bananas.sam-mesh.dev +``` + +* **Browser Flow**: The CLI will discover the OIDC credentials from the hub, print an OIDC authorization URL, and attempt to open your system's default web browser automatically. +* **Approval**: Log in with your corporate or identity credentials (e.g. Google Accounts), approve the authorization request, and return to the terminal. The node will automatically exchange the credentials for a Biscuit token and save it to `~/.config/sam-mesh/identity.json`. + +### Headless (Server) Login +If you are running the node on a remote server via SSH (without a web browser), force headless out-of-band mode: +```bash +sam-node join --hub https://bananas.sam-mesh.dev --headless +``` +The CLI will print a verification URL and code (e.g. `https://google.com/device` and `ABCD-EFGH`). Open this URL on your local laptop, enter the code, complete the login, and the remote terminal session will activate automatically. + +### Automatic Token Renewal +To allow long-lived nodes to automatically renew their tokens in the background, request offline access (refreshes the OIDC session): +```bash +sam-node join --hub https://bananas.sam-mesh.dev --offline-access +``` + +--- + +## 3. Phase 2: Running the Node daemon (`sam-node run`) + +Once authorized, you start the node gateway. The gateway spins up a local Model Context Protocol (MCP) server. + +Run the node daemon, securing the local API endpoint with a custom token: +```bash +sam-node run --api-token "my-agent-super-token-123" --bind-addr "127.0.0.1:8080" +``` + +### Key CLI Parameters +* `--bind-addr`: The local TCP address where the node's local HTTP server runs (default: `127.0.0.1:8080`). +* `--api-token`: A security token required by any local AI agent attempting to connect to your node. +* `--data-dir`: Custom path to store configurations and Biscuit tokens (defaults to `~/.config/sam-mesh` or env `SAM_DATA_DIR`). + +--- + +## 4. Connecting your AI Agents + +Your AI agent connects to the node's local MCP server. The local server translates standard MCP queries (like `listTools` or `callTool`) into secure P2P mesh commands. + +### Exposing the API +The local MCP endpoint is served via **HTTP Server-Sent Events (SSE)** at: +`http://127.0.0.1:8080/mcp/events` + +### Authentication +When configuring your agent client, you must pass the API token in the headers: +```http +Authorization: Bearer my-agent-super-token-123 +``` + +### Specific Integration Guides +Explore our step-by-step guides for integrating your node with popular agent clients: +* ๐Ÿš€ **[Google Gemini AI Agent](../integrations/gemini.md)**: Connect using Python scripts and the google-genai SDK. +* ๐Ÿ’ป **[Claude Desktop](../integrations/claude-desktop.md)**: Expose P2P tools directly to your Claude Desktop application menu. +* ๐Ÿค– **[Claude Code](../integrations/claude-code.md)**: Add your local node tools directly to the Claude CLI. +* ๐Ÿ”Œ **[OpenClaw](../integrations/openclaw.md)**: Setup remote tool bridges for OpenClaw clusters. diff --git a/site/content/docs/user/hub-configuration.md b/site/content/docs/user/hub-configuration.md new file mode 100644 index 0000000..1d90c39 --- /dev/null +++ b/site/content/docs/user/hub-configuration.md @@ -0,0 +1,101 @@ +--- +title: "Hub Configuration Guide" +linkTitle: "Hub Configuration" +weight: 10 +--- + +The `sam-hub` acts as the control plane for the Sovereign Agent Mesh. It is responsible for bridging user identities from OpenID Connect (OIDC) providers, issuing cryptographically signed Biscuit authorization tokens, and distributing network and tool policies to nodes. + +--- + +## 1. Core Services + +When you run `sam-hub`, it launches two core service endpoints: +1. **libp2p P2P Endpoint**: Used by `sam-node` clients to execute cryptographic handshakes and perform DHT resource discovery. +2. **HTTP/HTTPS Service Endpoint**: Used for health status checks (`/healthz`), prometheus metrics (`/metrics`), and administrative commands (like banning nodes). + +--- + +## 2. Command-Line Arguments & Environment Variables + +The hub is highly configurable. Each setting can be passed as a command-line flag or bound to a corresponding environment variable: + +| CLI Flag | Environment Variable | Default Value | Description | +| :--- | :--- | :--- | :--- | +| `--issuer` | `SAM_OIDC_ISSUER` | `https://accounts.google.com` | Comma-separated list of trusted OIDC Provider URLs. | +| `--client-id` | `SAM_OIDC_ID` | *None* | Client ID registered with the OIDC provider. | +| `--key` | `SAM_HUB_KEY` | *None* | Private Key seed (32-byte hexadecimal string) used to sign Biscuit tokens. | +| `--listen` | *None* | `[]` | Comma-separated libp2p multiaddrs to listen on (e.g. `/ip4/0.0.0.0/tcp/9090`). | +| `--bind-address` | *None* | `:9090` | Host and port to listen on for the HTTP/HTTPS admin service. | +| `--policy-file` | *None* | `policies.yaml` | Path to the YAML file defining authorization roles and bindings. | +| `--allowed-audiences` | *None* | `sam-audience` | Comma-separated list of allowed JWT audiences. | +| `--insecure-skip-tls-verify` | *None* | `false` | Set to `true` to skip certificate validation for development/testing OIDC providers. | +| `--keys-db` | *None* | `keys.db` | Path to the BoltDB file storing public/private keys for token validation. | +| `--admin-token` | *None* | *None* | Secret token string required in the HTTP Header `Authorization: Bearer ` for admin operations. | +| `--tls-cert-file` | *None* | *None* | Path to the TLS certificate file (enables HTTPS on the admin server). | +| `--tls-key-file` | *None* | *None* | Path to the TLS private key file. | + +--- + +## 3. Configuring Role-Based Policies (`policies.yaml`) + +The hub dynamically issues permissions inside the Biscuit token based on identity claims (users or groups) mapped to specific roles in the policy file. + +### Example Policy Mapping +Create a `policies.yaml` file in the directory where you run `sam-hub`: + +```yaml +version: v1alpha1 + +# Define authorization roles and their specific network/tool permissions +roles: + developer-role: + network: + allowedTargets: + - "10.0.0.0/8" + - "192.168.1.0/24" + mcp: + allowedServers: + - "local-shell-tools" + - "git-helper" + + admin-role: + network: + allowedTargets: + - "10.0.0.0/8" + - "172.16.0.0/12" + mcp: + allowedServers: + - "*" # Allow access to all MCP servers + +# Bind OIDC user emails or group claims to roles +bindings: + - user: "alice@example.com" + role: "admin-role" + - group: "eng-team" + role: "developer-role" +``` + +--- + +## 4. Bootstrapping Example + +Here is a script demonstrating how to boot the hub in a secure development environment using Google Accounts as the OIDC provider: + +```bash +# 1. Generate a secure 32-byte signing seed +export SAM_HUB_KEY=$(openssl rand -hex 32) + +# 2. Configure environment settings +export SAM_OIDC_ISSUER="https://accounts.google.com" +export SAM_OIDC_ID="my-google-client-id.apps.googleusercontent.com" + +# 3. Launch sam-hub with HTTPS and policies configured +./bin/sam-hub \ + --listen "/ip4/0.0.0.0/tcp/5001/udp/5001/quic-v1" \ + --policy-file "./policies.yaml" \ + --bind-address "0.0.0.0:9090" \ + --admin-token "super-secret-admin-token" \ + --tls-cert-file "/etc/sam/certs/hub.crt" \ + --tls-key-file "/etc/sam/certs/hub.key" +``` diff --git a/site/hugo.toml b/site/hugo.toml index 3faafc1..693ebd3 100644 --- a/site/hugo.toml +++ b/site/hugo.toml @@ -30,12 +30,54 @@ sectionPagesMenu = "main" [[module.imports]] path = "github.com/google/docsy/dependencies" +[menu] + [[menu.main]] + identifier = "docs" + name = "Overview" + title = "Overview" + url = "/docs/" + weight = 1 + + [[menu.main]] + identifier = "quickstart" + name = "Quick Start" + title = "Quick Start" + url = "/docs/quickstart/" + weight = 2 + + [[menu.main]] + identifier = "user" + name = "User Guides" + title = "User Guides" + url = "/docs/user/" + weight = 3 + + [[menu.main]] + identifier = "integrations" + name = "Agent Integrations" + title = "Agent Integrations" + url = "/docs/integrations/" + weight = 4 + + [[menu.main]] + identifier = "development" + name = "Developer Guides" + title = "Developer Guides" + url = "/docs/development/" + weight = 5 + [params] privacy_policy = "https://policies.google.com/privacy" github_repo = "https://github.com/google/sam" github_subdir = "docs" github_branch = "main" + [params.ui] + showLightDarkModeMenu = true + sidebar_menu_compact = true + sidebar_menu_foldable = true + ul_show = 1 + # Logo & branding colors will be customized via project styles [services] diff --git a/site/layouts/index.html b/site/layouts/index.html new file mode 100644 index 0000000..68e4509 --- /dev/null +++ b/site/layouts/index.html @@ -0,0 +1,59 @@ + + + + + {{ partial "head.html" . }} + + + +
+
+
+ +
+ +
+ +

SAM

+

Sovereign Agent Mesh

+

+ A zero-config, zero-trust decentralized P2P network built specifically for autonomous AI agents. +

+ + +
+ + +
+
+
+
+ + + +
+
bash - sam-node join
+
+
+
$ sam-node join --hub bananas.sam-mesh.dev
+
Discovering hub info from https://bananas.sam-mesh.dev...
+
... [OIDC Device Authorization Flow Completed] ...
+
Successfully joined the Sovereign Agent Mesh!
+
$ sam-node run
+
Using stored identity.
+
... [Mesh and DHT Initialization] ...
+
[DHT] Bootstrapping DHT with connected hub...
+
SAM Node Online.
+
PeerID: 12D3KooWQPXLN3mZ2mfYtNJWqLr2BBMxjPcVhQxydJNkanYH78eR
+
+
+
+
+ + {{ partial "scripts.html" . }} + + + \ No newline at end of file diff --git a/site/layouts/partials/hooks/head-end.html b/site/layouts/partials/hooks/head-end.html index c1b043e..7032d9f 100644 --- a/site/layouts/partials/hooks/head-end.html +++ b/site/layouts/partials/hooks/head-end.html @@ -1,3 +1,10 @@ + + + diff --git a/site/static/favicon.ico b/site/static/favicon.ico index 3d2a0db..96dcac4 100644 Binary files a/site/static/favicon.ico and b/site/static/favicon.ico differ diff --git a/site/static/favicon.png b/site/static/favicon.png index 55b4f61..ea3494f 100644 Binary files a/site/static/favicon.png and b/site/static/favicon.png differ diff --git a/site/static/favicons/android-144x144.png b/site/static/favicons/android-144x144.png index 55b4f61..9c45186 100644 Binary files a/site/static/favicons/android-144x144.png and b/site/static/favicons/android-144x144.png differ diff --git a/site/static/favicons/android-192x192.png b/site/static/favicons/android-192x192.png index 55b4f61..d470eda 100644 Binary files a/site/static/favicons/android-192x192.png and b/site/static/favicons/android-192x192.png differ diff --git a/site/static/favicons/android-36x36.png b/site/static/favicons/android-36x36.png index 55b4f61..f41ac91 100644 Binary files a/site/static/favicons/android-36x36.png and b/site/static/favicons/android-36x36.png differ diff --git a/site/static/favicons/android-48x48.png b/site/static/favicons/android-48x48.png index 55b4f61..1ab92f1 100644 Binary files a/site/static/favicons/android-48x48.png and b/site/static/favicons/android-48x48.png differ diff --git a/site/static/favicons/android-72x72.png b/site/static/favicons/android-72x72.png index 55b4f61..05b9482 100644 Binary files a/site/static/favicons/android-72x72.png and b/site/static/favicons/android-72x72.png differ diff --git a/site/static/favicons/android-96x96.png b/site/static/favicons/android-96x96.png index 55b4f61..edbb62d 100644 Binary files a/site/static/favicons/android-96x96.png and b/site/static/favicons/android-96x96.png differ diff --git a/site/static/favicons/apple-touch-icon-180x180.png b/site/static/favicons/apple-touch-icon-180x180.png index 55b4f61..f2b62cf 100644 Binary files a/site/static/favicons/apple-touch-icon-180x180.png and b/site/static/favicons/apple-touch-icon-180x180.png differ diff --git a/site/static/favicons/apple-touch-icon.png b/site/static/favicons/apple-touch-icon.png index 55b4f61..f2b62cf 100644 Binary files a/site/static/favicons/apple-touch-icon.png and b/site/static/favicons/apple-touch-icon.png differ diff --git a/site/static/favicons/favicon-1024.png b/site/static/favicons/favicon-1024.png index 55b4f61..ea3494f 100644 Binary files a/site/static/favicons/favicon-1024.png and b/site/static/favicons/favicon-1024.png differ diff --git a/site/static/favicons/favicon-16x16.png b/site/static/favicons/favicon-16x16.png index 55b4f61..991b899 100644 Binary files a/site/static/favicons/favicon-16x16.png and b/site/static/favicons/favicon-16x16.png differ diff --git a/site/static/favicons/favicon-256.png b/site/static/favicons/favicon-256.png index 55b4f61..9dc112d 100644 Binary files a/site/static/favicons/favicon-256.png and b/site/static/favicons/favicon-256.png differ diff --git a/site/static/favicons/favicon-32x32.png b/site/static/favicons/favicon-32x32.png index 55b4f61..52b2415 100644 Binary files a/site/static/favicons/favicon-32x32.png and b/site/static/favicons/favicon-32x32.png differ diff --git a/site/static/favicons/favicon.ico b/site/static/favicons/favicon.ico index 3d2a0db..96dcac4 100644 Binary files a/site/static/favicons/favicon.ico and b/site/static/favicons/favicon.ico differ diff --git a/site/static/favicons/favicon.png b/site/static/favicons/favicon.png index 55b4f61..ea3494f 100644 Binary files a/site/static/favicons/favicon.png and b/site/static/favicons/favicon.png differ diff --git a/site/static/favicons/pwa-192x192.png b/site/static/favicons/pwa-192x192.png index 55b4f61..d470eda 100644 Binary files a/site/static/favicons/pwa-192x192.png and b/site/static/favicons/pwa-192x192.png differ diff --git a/site/static/favicons/pwa-512x512.png b/site/static/favicons/pwa-512x512.png index 55b4f61..ea3494f 100644 Binary files a/site/static/favicons/pwa-512x512.png and b/site/static/favicons/pwa-512x512.png differ diff --git a/site/static/favicons/tile150x150.png b/site/static/favicons/tile150x150.png index 55b4f61..127cf2d 100644 Binary files a/site/static/favicons/tile150x150.png and b/site/static/favicons/tile150x150.png differ diff --git a/site/static/favicons/tile310x150.png b/site/static/favicons/tile310x150.png index 55b4f61..22bb3c2 100644 Binary files a/site/static/favicons/tile310x150.png and b/site/static/favicons/tile310x150.png differ diff --git a/site/static/favicons/tile310x310.png b/site/static/favicons/tile310x310.png index 55b4f61..42e8d76 100644 Binary files a/site/static/favicons/tile310x310.png and b/site/static/favicons/tile310x310.png differ diff --git a/site/static/favicons/tile70x70.png b/site/static/favicons/tile70x70.png index 55b4f61..9eeab5b 100644 Binary files a/site/static/favicons/tile70x70.png and b/site/static/favicons/tile70x70.png differ diff --git a/site/static/install.sh b/site/static/install.sh new file mode 100755 index 0000000..99763bb --- /dev/null +++ b/site/static/install.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +set -e + +REPO="google/sam" +INSTALL_DIR="/usr/local/bin" + +echo "Installing SAM from $REPO..." + +# Get OS and Arch +OS="$(uname -s)" +case "${OS}" in + Linux*) OS_NAME="Linux";; + Darwin*) OS_NAME="Darwin";; + *) echo "Unsupported OS: ${OS}"; exit 1;; +esac + +ARCH="$(uname -m)" +case "${ARCH}" in + x86_64*) ARCH_NAME="x86_64";; + aarch64*) ARCH_NAME="arm64";; + arm64*) ARCH_NAME="arm64";; + *) echo "Unsupported architecture: ${ARCH}"; exit 1;; +esac + +# Get latest release version +echo "Fetching latest release information..." +LATEST_RELEASE_URL="https://api.github.com/repos/${REPO}/releases/latest" +VERSION=$(curl -s $LATEST_RELEASE_URL | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + +if [ -z "$VERSION" ]; then + echo "Error: Could not find the latest release." + exit 1 +fi + +echo "Found latest version: ${VERSION}" + +# Construct download URL (matches goreleaser name template) +TAR_NAME="sam_${OS_NAME}_${ARCH_NAME}.tar.gz" +DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${VERSION}/${TAR_NAME}" + +# Create a temporary directory +TMP_DIR=$(mktemp -d) +cd "$TMP_DIR" + +echo "Downloading ${DOWNLOAD_URL}..." +if ! curl -sfL -o "${TAR_NAME}" "${DOWNLOAD_URL}"; then + echo "Error: Failed to download ${DOWNLOAD_URL}" + rm -rf "$TMP_DIR" + exit 1 +fi + +echo "Extracting..." +tar -xzf "${TAR_NAME}" + +echo "Installing to ${INSTALL_DIR} (may require sudo)..." +# In some environments, sudo might not be available or required +if [ -w "$INSTALL_DIR" ]; then + mv sam-node sam-hub mcp-client "$INSTALL_DIR/" 2>/dev/null || true +else + sudo mv sam-node sam-hub mcp-client "$INSTALL_DIR/" 2>/dev/null || true +fi + +# Cleanup +cd - > /dev/null +rm -rf "$TMP_DIR" + +echo "Successfully installed SAM (${VERSION}) to ${INSTALL_DIR}" +echo "Run 'sam-node --help' to get started."