diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-27 21:16:16 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-27 21:16:16 +0300 |
| commit | 3325304f89d56990f3134a3d01749e5de498725d (patch) | |
| tree | b10823a00f5e0de8b394c91b30d3fb2091d452c2 | |
| parent | 7ebc72f3f5de24a293db144cd1745cea52c3e717 (diff) | |
ci: fix build checks and mobile nav
| -rw-r--r-- | .github/workflows/nix.yml | 9 | ||||
| -rw-r--r-- | nix/package.nix | 2 | ||||
| -rw-r--r-- | tests/live_handoff.rs | 83 | ||||
| -rw-r--r-- | website/astro.config.mjs | 7 | ||||
| -rw-r--r-- | website/css/style.css | 84 | ||||
| -rw-r--r-- | website/index.html | 20 | ||||
| -rw-r--r-- | website/src/components/MarketingLayout.astro | 20 | ||||
| -rw-r--r-- | website/src/components/SiteTitle.astro | 2 | ||||
| -rw-r--r-- | website/src/pages/compare.astro | 20 |
9 files changed, 219 insertions, 28 deletions
diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index 81306b1a..142b4054 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -38,15 +38,6 @@ jobs: experimental-features = nix-command flakes always-allow-substitutes = true - - name: Enable Magic Nix Cache - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository - uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39 # v13 - continue-on-error: true - with: - source-tag: v0.1.6 - use-flakehub: disabled - diagnostic-endpoint: "" - - name: Run Nix flake check run: | nix flake check --print-build-logs diff --git a/nix/package.nix b/nix/package.nix index ba9206d8..ab23e31c 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -42,7 +42,7 @@ rustPlatform.buildRustPackage { ); }; - cargoLock.lockFile = ../Cargo.lock; + cargoHash = "sha256-5WvdZUD0Axr6xQ9Nm1XV1eJ0w4xUl8BQDnNs7pv6C8o="; nativeBuildInputs = [ git diff --git a/tests/live_handoff.rs b/tests/live_handoff.rs index b8e9ad76..d9a8b34f 100644 --- a/tests/live_handoff.rs +++ b/tests/live_handoff.rs @@ -21,6 +21,11 @@ struct SpawnedHerdr { child: Box<dyn Child + Send + Sync>, } +struct RequestError { + retryable: bool, + message: String, +} + impl Drop for SpawnedHerdr { fn drop(&mut self) { let pid = self.child.process_id(); @@ -162,14 +167,56 @@ fn spawn_default_session_server(config_home: &Path, runtime_dir: &Path) -> Spawn } } -fn request(socket_path: &Path, request: serde_json::Value) -> serde_json::Value { - let mut stream = UnixStream::connect(socket_path).unwrap(); - stream.write_all(request.to_string().as_bytes()).unwrap(); - stream.write_all(b"\n").unwrap(); - stream.flush().unwrap(); +fn try_request( + socket_path: &Path, + request: serde_json::Value, +) -> Result<serde_json::Value, RequestError> { + let mut stream = UnixStream::connect(socket_path).map_err(|err| RequestError { + retryable: true, + message: format!("connect {}: {err}", socket_path.display()), + })?; + let request_text = request.to_string(); + stream + .write_all(request_text.as_bytes()) + .map_err(|err| RequestError { + retryable: true, + message: format!("write request to {}: {err}", socket_path.display()), + })?; + stream.write_all(b"\n").map_err(|err| RequestError { + retryable: true, + message: format!("write newline to {}: {err}", socket_path.display()), + })?; + stream.flush().map_err(|err| RequestError { + retryable: true, + message: format!("flush request to {}: {err}", socket_path.display()), + })?; let mut line = String::new(); - BufReader::new(stream).read_line(&mut line).unwrap(); - serde_json::from_str(&line).unwrap() + BufReader::new(stream) + .read_line(&mut line) + .map_err(|err| RequestError { + retryable: true, + message: format!("read response from {}: {err}", socket_path.display()), + })?; + if line.is_empty() { + return Err(RequestError { + retryable: true, + message: format!( + "empty response from {} for request {request_text}", + socket_path.display() + ), + }); + } + serde_json::from_str(&line).map_err(|err| RequestError { + retryable: false, + message: format!( + "parse response from {} for request {request_text}: {err}; response was {line:?}", + socket_path.display() + ), + }) +} + +fn request(socket_path: &Path, request: serde_json::Value) -> serde_json::Value { + try_request(socket_path, request).unwrap_or_else(|err| panic!("{}", err.message)) } fn assert_ok(response: serde_json::Value) { @@ -181,19 +228,25 @@ fn assert_ok(response: serde_json::Value) { fn wait_for_api(socket_path: &Path, timeout: Duration) { let deadline = Instant::now() + timeout; + let mut last_error = String::new(); while Instant::now() < deadline { - if UnixStream::connect(socket_path).is_ok() { - let response = request( - socket_path, - serde_json::json!({"id":"test:ping","method":"ping","params":{}}), - ); - if response.get("result").is_some() { - return; + match try_request( + socket_path, + serde_json::json!({"id":"test:ping","method":"ping","params":{}}), + ) { + Ok(response) if response.get("result").is_some() => return, + Ok(response) => panic!("api ping returned non-success response: {response}"), + Err(err) if !err.retryable => panic!("{}", err.message), + Err(err) => { + last_error = err.message; } } thread::sleep(Duration::from_millis(25)); } - panic!("api did not become ready at {}", socket_path.display()); + panic!( + "api did not become ready at {}; last error: {last_error}", + socket_path.display() + ); } fn wait_for_output(socket_path: &Path, pane_id: &str, needle: &str) { diff --git a/website/astro.config.mjs b/website/astro.config.mjs index 6adb9e5b..badd2873 100644 --- a/website/astro.config.mjs +++ b/website/astro.config.mjs @@ -125,6 +125,13 @@ export default defineConfig({ { label: 'Agent skill file', slug: 'docs/agent-skill' }, ], }, + { + label: 'Updates', + items: [ + { label: 'Releases', link: '/releases/' }, + { label: 'Blog', link: '/blog/' }, + ], + }, ], }), ], diff --git a/website/css/style.css b/website/css/style.css index fcadb011..74be689f 100644 --- a/website/css/style.css +++ b/website/css/style.css @@ -433,6 +433,82 @@ samp { font-family: var(--mono); } +.nav-menu { + position: relative; + display: none; + margin-left: auto; +} + +.nav-menu-button { + display: inline-flex; + align-items: center; + justify-content: center; + flex-direction: column; + gap: 0.22rem; + width: 2.1rem; + height: 2.1rem; + border: 1px solid var(--line); + border-radius: var(--radius-md); + color: var(--ink-soft); + cursor: pointer; + list-style: none; + transition: + color 120ms ease, + border-color 120ms ease, + background 120ms ease; +} + +.nav-menu-button::-webkit-details-marker { + display: none; +} + +.nav-menu-button::marker { + content: ""; +} + +.nav-menu-button span { + display: block; + width: 0.92rem; + height: 1px; + background: currentColor; +} + +.nav-menu-button:hover, +.nav-menu[open] .nav-menu-button { + color: var(--accent); + border-color: color-mix(in srgb, var(--accent) 38%, var(--line)); + background: var(--accent-soft); +} + +.nav-menu-panel { + position: absolute; + top: calc(100% + 0.65rem); + right: 0; + z-index: 30; + display: grid; + min-width: min(18rem, calc(100vw - 2rem)); + padding: 0.35rem; + border: 1px solid var(--line-strong); + border-radius: var(--radius-md); + background: var(--bg-elevated); + box-shadow: 0 16px 44px rgba(0, 0, 0, 0.16); +} + +.nav-menu-panel a { + border-radius: var(--radius-sm); + padding: 0.62rem 0.7rem; + color: var(--ink-soft); + font-family: var(--mono); + font-size: 0.86rem; + font-weight: 600; +} + +.nav-menu-panel a:hover, +.nav-menu-panel a[aria-current="page"] { + background: var(--accent-soft); + color: var(--accent); +} + .nav-links a, .footer a, .inline-links a { @@ -2462,10 +2538,18 @@ td:last-child { padding-inline: 1rem; } + .nav-menu { + display: block; + } + .nav-links { display: none; } + .nav-tools { + display: none; + } + .section, .awareness-section, .demo-section, diff --git a/website/index.html b/website/index.html index a844442d..1de94a14 100644 --- a/website/index.html +++ b/website/index.html @@ -57,7 +57,7 @@ document.documentElement.setAttribute("data-palette", saved || system); })(); </script> - <link rel="stylesheet" href="/css/style.css?v=20" /> + <link rel="stylesheet" href="/css/style.css?v=21" /> </head> <body> <header class="site-header"> @@ -66,6 +66,24 @@ <span class="brand-logo" aria-hidden="true"></span> <span>herdr</span> </a> + <details class="nav-menu"> + <summary class="nav-menu-button" aria-label="Open navigation"> + <span></span> + <span></span> + <span></span> + </summary> + <div class="nav-menu-panel"> + <a href="/">Home</a> + <a href="/compare/">Compare</a> + <a href="/releases/">Releases</a> + <a href="/blog/">Blog</a> + <a href="/docs/quick-start/">Quick start</a> + <a href="/docs/">Docs</a> + <a href="/docs/socket-api/">API</a> + <a href="/docs/install/">Install</a> + <a href="https://github.com/ogulcancelik/herdr">GitHub</a> + </div> + </details> <div class="nav-links"> <a href="/">Home</a> <a href="/compare/">Compare</a> diff --git a/website/src/components/MarketingLayout.astro b/website/src/components/MarketingLayout.astro index 5e39e011..9ecd7ac3 100644 --- a/website/src/components/MarketingLayout.astro +++ b/website/src/components/MarketingLayout.astro @@ -48,7 +48,7 @@ const canonicalUrl = new URL(canonicalPath, 'https://herdr.dev').toString(); document.documentElement.setAttribute("data-palette", saved || system); })(); </script> - <link rel="stylesheet" href="/css/style.css" /> + <link rel="stylesheet" href="/css/style.css?v=21" /> </head> <body> <header class="site-header"> @@ -57,6 +57,24 @@ const canonicalUrl = new URL(canonicalPath, 'https://herdr.dev').toString(); <span class="brand-logo" aria-hidden="true"></span> <span>herdr</span> </a> + <details class="nav-menu"> + <summary class="nav-menu-button" aria-label="Open navigation"> + <span></span> + <span></span> + <span></span> + </summary> + <div class="nav-menu-panel"> + <a href="/">Home</a> + <a href="/compare/">Compare</a> + <a href="/releases/">Releases</a> + <a href="/blog/">Blog</a> + <a href="/docs/quick-start/">Quick start</a> + <a href="/docs/">Docs</a> + <a href="/docs/socket-api/">API</a> + <a href="/docs/install/">Install</a> + <a href="https://github.com/ogulcancelik/herdr">GitHub</a> + </div> + </details> <div class="nav-links"> <a href="/">Home</a> <a href="/compare/">Compare</a> diff --git a/website/src/components/SiteTitle.astro b/website/src/components/SiteTitle.astro index ee979e9d..1173f2b6 100644 --- a/website/src/components/SiteTitle.astro +++ b/website/src/components/SiteTitle.astro @@ -9,6 +9,8 @@ const { siteTitle, siteTitleHref } = Astro.locals.starlightRoute; </a> <nav class="title-nav" aria-label="Primary"> <a href="/docs/">Docs</a> + <a href="/releases/">Releases</a> + <a href="/blog/">Blog</a> </nav> </div> diff --git a/website/src/pages/compare.astro b/website/src/pages/compare.astro index 0c173f6f..96f1a7ee 100644 --- a/website/src/pages/compare.astro +++ b/website/src/pages/compare.astro @@ -45,7 +45,7 @@ document.documentElement.setAttribute("data-palette", saved || system); })(); </script> - <link rel="stylesheet" href="/css/style.css?v=compare2" /> + <link rel="stylesheet" href="/css/style.css?v=21" /> </head> <body> <header class="site-header"> @@ -54,6 +54,24 @@ <span class="brand-logo" aria-hidden="true"></span> <span>herdr</span> </a> + <details class="nav-menu"> + <summary class="nav-menu-button" aria-label="Open navigation"> + <span></span> + <span></span> + <span></span> + </summary> + <div class="nav-menu-panel"> + <a href="/">Home</a> + <a href="/compare/" aria-current="page">Compare</a> + <a href="/releases/">Releases</a> + <a href="/blog/">Blog</a> + <a href="/docs/quick-start/">Quick start</a> + <a href="/docs/">Docs</a> + <a href="/docs/socket-api/">API</a> + <a href="/docs/install/">Install</a> + <a href="https://github.com/ogulcancelik/herdr">GitHub</a> + </div> + </details> <div class="nav-links"> <a href="/">Home</a> <a href="/compare/" aria-current="page">Compare</a> |
