mount LevelUpInbox + document Gemini env vars

1. Dashboard.tsx — mount LevelUpInbox as a bottom panel on the
   MISSIONS tier sidebar (below MissionsList, above the tier rail).
   Capped at 38% height so it never crowds the mission list; scrolls
   independently when the proposal count grows.

2. deploy/compose/.env.example — document GEMINI_API_KEY +
   CLAWMATES_REFINER_MODEL + CLAWMATES_LEVEL_UP_MODEL. Refine + Level-
   Up silently 500 without the key; the model overrides default to
   gemini-2.5-flash so setting the key is the only required step.

Closes the two loose ends I called out last turn (inbox not mounted,
env vars undocumented). The full flow — Refine → mission launch →
security scan / benchmark → level-up review — is now wireable
end-to-end on a fresh deploy just by copying .env.example → .env
and setting POSTGRES_PASSWORD + GEMINI_API_KEY.
This commit is contained in:
Omar Sobh
2026-07-19 19:14:25 -07:00
parent 9bac84c645
commit 5b7cb55d21
2 changed files with 33 additions and 9 deletions
+8
View File
@@ -25,6 +25,14 @@ CLAWMATES_BOOTSTRAP_CREDITS=1250
# and provide the key here (uncomment): # and provide the key here (uncomment):
# ANTHROPIC_API_KEY=sk-ant-... # ANTHROPIC_API_KEY=sk-ant-...
# --- Gemini (mission Refine + agent/team Level-Up) --------------------------
# Both features call Gemini via generativelanguage.googleapis.com. Without a
# key, the Refine button and Level-Up buttons return 500.
# Model overrides default to gemini-2.5-flash (cheap, JSON-mode-native).
# GEMINI_API_KEY=AIza...
# CLAWMATES_REFINER_MODEL=gemini-2.5-flash
# CLAWMATES_LEVEL_UP_MODEL=gemini-2.5-flash
# --- Auth mode (optional) --------------------------------------------------- # --- Auth mode (optional) ---------------------------------------------------
# clawmates.toml defaults to mode = "local". For Clerk, set mode = "clerk" # clawmates.toml defaults to mode = "local". For Clerk, set mode = "clerk"
# and auth.issuer_url there, then supply the frontend keys (see docs/clerk.md): # and auth.issuer_url there, then supply the frontend keys (see docs/clerk.md):
@@ -24,6 +24,7 @@ import { WorldCanvas } from "../world/WorldCanvas";
import { ObservePanel } from "../observe/ObservePanel"; import { ObservePanel } from "../observe/ObservePanel";
import { StructureTree, orgNode, type TreeItem } from "./StructureTree"; import { StructureTree, orgNode, type TreeItem } from "./StructureTree";
import { MissionsList } from "./MissionsList"; import { MissionsList } from "./MissionsList";
import { LevelUpInbox } from "./LevelUpInbox";
import { MissionCanvas } from "./MissionCanvas"; import { MissionCanvas } from "./MissionCanvas";
import { RepoList } from "./RepoList"; import { RepoList } from "./RepoList";
import { RepoCanvas } from "./RepoCanvas"; import { RepoCanvas } from "./RepoCanvas";
@@ -720,15 +721,30 @@ export function Dashboard({ user, orgs, claws }: { user?: { display_name?: strin
)} )}
{isMissions ? ( {isMissions ? (
<MissionsList <div style={{ display: "flex", flexDirection: "column", minHeight: 0, flex: 1 }}>
selectedId={missionsSel} <div style={{ flex: "1 1 0", minHeight: 0, overflow: "auto" }}>
onSelect={setMissionsSel} <MissionsList
refreshKey={missionsRefresh} selectedId={missionsSel}
onCreated={(id) => { onSelect={setMissionsSel}
setMissionsSel(id); refreshKey={missionsRefresh}
setMissionsRefresh((n) => n + 1); onCreated={(id) => {
}} setMissionsSel(id);
/> setMissionsRefresh((n) => n + 1);
}}
/>
</div>
<div
style={{
flex: "none",
borderTop: "1px solid rgba(255,255,255,.06)",
padding: "10px 12px",
maxHeight: "38%",
overflow: "auto",
}}
>
<LevelUpInbox />
</div>
</div>
) : isRepos ? ( ) : isRepos ? (
<RepoList <RepoList
selectedId={repoSel} selectedId={repoSel}