From 99ad456adfd0143a53dbf4ef73a283642c1436e7 Mon Sep 17 00:00:00 2001
From: Daniel Grzelak <59827851+pan-daniel@users.noreply.github.com>
Date: Mon, 1 Jun 2026 04:50:50 +0200
Subject: [PATCH] fix: group cookbook dependencies into Odysseus and Server
sections (#144)
* fix: group cookbook dependencies into Odysseus and Server sections
* refactor: tidy dependency render with guard clauses and a section-header class
---
static/js/cookbook.js | 67 ++++++++++++++++++++++---------------------
static/style.css | 15 ++++++++++
2 files changed, 50 insertions(+), 32 deletions(-)
diff --git a/static/js/cookbook.js b/static/js/cookbook.js
index b4802fc..ce299c7 100644
--- a/static/js/cookbook.js
+++ b/static/js/cookbook.js
@@ -523,39 +523,42 @@ async function _fetchDependencies() {
const pkgs = data.packages || [];
if (!pkgs.length) { list.innerHTML = '
No packages found
'; return; }
const _winUnsupported = new Set(['diffusers', 'hf_transfer', 'vllm', 'rembg', 'gfpgan']);
- // When a non-local server is selected, the Local-only packages aren't
- // relevant to it — hide them so the list shows just that server's packages.
- const _viewingRemote = !!(_dsel && _dsel.value && _dsel.value !== 'local');
- let html = '';
- for (const pkg of pkgs) {
+
+ const _statusTag = (pkg, isLocal, isSystemDep, winBlocked) => {
+ if (winBlocked) return `N/A`;
+ if (pkg.installed && isSystemDep) return `Installed`;
+ if (pkg.installed) return ``;
+ if (isSystemDep) return `Missing`;
+ return ``;
+ };
+
+ const _depRow = (pkg) => {
const isLocal = pkg.target === 'local';
- if (_viewingRemote && isLocal) continue;
- const winBlocked = !isLocal && _isWindows() && _winUnsupported.has(pkg.name);
- const targetLabel = isLocal ? 'Local' : 'GPU server';
const isSystemDep = pkg.kind === 'system';
- html += ``;
- html += `
`;
- html += `
${esc(pkg.name)}
`;
- html += `
${esc(pkg.desc)}
`;
- html += `
`;
- html += `
${targetLabel}`;
- html += `
${esc(pkg.category)}`;
- if (winBlocked) {
- html += `
N/A`;
- } else if (pkg.installed) {
- if (isSystemDep) {
- html += `
Installed`;
- } else {
- html += `
`;
- }
- } else if (isSystemDep) {
- html += `
Missing`;
- } else {
- html += `
`;
- }
- html += `
`;
- }
- list.innerHTML = html;
+ const winBlocked = !isLocal && _isWindows() && _winUnsupported.has(pkg.name);
+ return ``
+ + `
`
+ + `
${esc(pkg.name)}
`
+ + `
${esc(pkg.desc)}
`
+ + `
`
+ + `
${esc(pkg.category)}`
+ + _statusTag(pkg, isLocal, isSystemDep, winBlocked)
+ + `
`;
+ };
+
+ const _section = (title, note, items) =>
+ items.length
+ ? `${title}${note}
` + items.map(_depRow).join('')
+ : '';
+
+ const _viewingRemote = !!(_dsel && _dsel.value && _dsel.value !== 'local');
+ const _appDeps = pkgs.filter(p => p.target === 'local');
+ const _serverDeps = pkgs.filter(p => p.target !== 'local');
+
+ list.innerHTML = [
+ _viewingRemote ? '' : _section('Odysseus app', 'Run inside the Odysseus app itself.', _appDeps),
+ _section('Server', 'Run on the server chosen above (Local, or a remote box over SSH).', _serverDeps),
+ ].join('');
// Shared install/update routine — used by the Install button and the
// "Update" item in an installed package's ⋮ menu. `upgrade` adds pip -U;
@@ -1475,7 +1478,7 @@ function _renderRecipes() {
html += _buildServerOpts(false);
html += '';
html += '';
- html += 'Optional packages that extend Odysseus capabilities. Install on local or remote servers.
';
+ html += 'Optional packages that extend Odysseus capabilities.
';
html += '';
html += '';
diff --git a/static/style.css b/static/style.css
index 3ab47fb..60f9f46 100644
--- a/static/style.css
+++ b/static/style.css
@@ -18007,6 +18007,21 @@ body.gallery-selecting .gallery-dl-btn,
.cookbook-settings-stack.hidden { display: none; }
.cookbook-dep-row.cookbook-dep-blocked { opacity: 0.4; }
.cookbook-dep-info { flex: 1; min-width: 0; }
+.cookbook-dep-section {
+ display: flex;
+ align-items: baseline;
+ gap: 8px;
+ margin: 12px 2px 4px;
+}
+.cookbook-dep-section-title {
+ font-size: 11px;
+ font-weight: 600;
+ letter-spacing: 0.03em;
+}
+.cookbook-dep-section-note {
+ font-size: 10px;
+ color: color-mix(in srgb, var(--fg) 50%, transparent);
+}
.cookbook-dep-tag {
font-size: 9px;
padding: 0 8px;