Release dev → master: agent OS control framework, macOS-dark theme, store/desktop/chat redesigns#883
Conversation
…ed (#843) * fix(store): model install works when rkllama runs but is unregistered The model-store Install button failed for rkllama models on the Pi with 'backend install failed: script not found: scripts/install-rkllama.sh'. Two compounding bugs (found by live test of the store route on the Pi): 1. get_device_capability built installed_backends only from the registry, so a running-but-unregistered rkllama was treated as not installed and every model install took the install_chain branch. Now it also live-probes rkllama (new rkllama_is_running() checks the taOS + legacy ports) and adds it, so the resolver returns action=use and goes straight to the model pull. 2. The rkllama backend manifest's install.script pointed at a non-existent scripts/install-rkllama.sh; repointed to the real scripts/install-rknpu.sh as a safety net for when the chain is genuinely needed. This is the real symptom behind the #783 store-UI caveat; the rkllama connection logic itself was already correct (probes 7833 then falls back to 8080). Adds rkllama_is_running tests. * fix(store): offload the rkllama liveness probe to a thread Addresses a Gitar review note: rkllama_is_running() does blocking socket I/O, and get_device_capability is async, so run it via asyncio.to_thread to avoid stalling the event loop during a model install. * fix(store): drop the manifest script repoint from this PR Qodo flagged that scripts/install-rknpu.sh exit-0-false-succeeds in a non-interactive shell without TAOS_RKNPU_SETUP, so the install_chain would mark rkllama installed when it did nothing. That is worse than the original loud 'script not found'. The chain path is not the bug this PR fixes (the live-probe handles the running-rkllama case), so revert the manifest change and track the chain fix separately. * fix(store): log the rkllama runtime-detection fallback instead of swallowing it
* docs: brand contact details to info@taos.my and add taos.my website link
Swaps the personal gmail for the branded info@taos.my across the README, LICENSE
commercial-contact, code of conduct enforcement, CONTRIBUTING, and getting-started
docs, and surfaces taos.my as the project website. Leaves the gitea-migration
runbook config value (infra, not public contact) untouched.
* docs(readme): rename the TinyAgentOS brand to taOS
Replaces the long-form 'TinyAgentOS' display name with 'taOS' throughout the
README, keeping one bracketed mention up top ('taOS (short for TinyAgentOS)')
so first-time readers learn what taOS stands for. Lowercase tinyagentos in
URLs, paths, and the package/repo slug is unchanged.
…efault (#848) Adds a third builtin theme (Default dark / Light / Matrix Terminal). Three parts: - builtin-themes.ts: the Light palette over the existing --color-shell-* tokens (cool off-white body, slate accent, frosted near-white chrome, softer shadows, light wallpaper). Contrast-checked: body ink hits ~14:1, secondary ~6.4:1. - theme-store.ts: applyThemeConfig now derives a light/dark scheme from the theme's --color-shell-bg luminance and tags the root data-scheme. Works for the builtin Light theme and any agent-generated light theme alike. - tokens.css: a light-scheme compatibility layer that inverts the ~800 hardcoded white-overlay utilities (bg-white/N, border-white/N) and ~140 text-white uses that apps still carry, so they read dark-on-light instead of vanishing. Gated on data-scheme=light via attribute selectors whose specificity beats Tailwind utilities without !important, so the dark theme is provably untouched. The dark Default theme is unchanged. Verified live: computed styles invert under the light scheme and stay identical under dark.
… target to es2022 (#849) Dependabot flagged esbuild < 0.28.1 (missing binary integrity verification, RCE via NPM_CONFIG_REGISTRY). esbuild is a transitive dep of vite 6, and the bump needs a build target of es2022+ (vite's default es2020/chrome87 target hit an esbuild 0.28 destructuring-downlevel error). es2022 covers Chrome 94+, Safari 15.4+, Firefox 93+ — all 2021/2022, fine for a modern self-hosted desktop. Pinned via the existing overrides block. tsc + vite build verified green.
…side the input) (#850) The attach and screenshot buttons sat as detached siblings to the left of a tall textarea, sinking to the bottom-left and reading as out of place. Wrap them into one rounded composer (chat-app convention): attach + screenshot as borderless ghost icons inside on the left, the field borderless in the middle, a filled accent send button on the right, bottom-aligned so the icons sit on the last line as the field grows. Shell tokens only, so it flips for the Light theme; switched the send glyph to an up-arrow.
…(Install Update 500) (#852) * fix(update): reset desktop/package-lock.json before the ff-only pull The desktop rebuild runs npm install, which rewrites desktop/package-lock.json and leaves it dirty. When an incoming update also touches that file (e.g. the esbuild bump), git pull --ff-only refuses to overwrite the local change and the Install Update button 500s. The endpoint already restored tsbuildinfo and static/desktop before pulling; add package-lock.json to that reset so updates keep working across rebuilds. * docs(update-log): record the package-lock.json Install Update 500 (#852)
* feat(agents): redesign the Agents app to Apple-grade cards (identity tile, live status, refined states) * feat(agents): show the system agent in the standard layout with a model indicator line The taOS system agent baked its model into the display name (taOS agent - <model>). Render it like any standard agent instead (name 'taOS agent', framework 'opencode' sub-label) and move the model to a new indicator line (extensible for future indicators) via an optional Agent.model field + an IndicatorRow on the card. * feat(agents): drop the System pill from the system agent card Keep the subtle elevated ring/tint, just remove the 'System' chip per design review. Update the AgentRow test to assert protected hides destructive actions without the chip. * fix(agents): don't repeat the host as the sub-label for framework-less agents For none/generic-framework agents the sub-label fell back to the host, which is already shown in the metadata column, so the host appeared twice on the card (Gitar review). Omit the sub-label when there's no framework instead.
…low-ups, refined reactions/threads) (#853) * feat(chat): Slack-polish the message rows (avatar gutter, grouped follow-ups, refined reactions/threads) * fix(chat): use a single sky shade for the agent accent (drop OS-keyed dark: variants) taOS themes via data-scheme + tokens, not Tailwind's dark: class, so dark: keyed off the OS preference rather than the active taOS theme. Use one sky shade legible on both the dark and light theme backgrounds instead.
A quick-access dropdown in the top bar to stop a runaway agent without opening
the Agents app: Kill all agents (with a live running count) plus each running
agent by name. Every action is gated behind a confirmation dialog (kill is
destructive). Wired to POST /api/agents/bulk/stop and /api/agents/{name}/stop;
follows the existing Power-menu dropdown pattern (radix), confirm via radix
Dialog, all on shell tokens.
…857) (#859) * fix(agents): surface kill failures instead of closing silently (Gitar review on #857) - If a stop request fails, keep the dialog open and show an error + 'Try again' rather than closing as if it succeeded (silent-failure fix). - Retain the last target in a 'shown' state so the dialog title no longer flashes 'Kill ?' during the close animation. - Add a render/contract test for AgentKillSwitch. * fix(agents): reset kill-switch error state on dialog close + reset test stubs Address bot review: clear the failed state when the confirm dialog closes (via Cancel or dismiss) so a stale error cannot linger into the next open; add afterEach(unstubAllGlobals) to the test.
…x Terminal) (#860) The theme chooser now shows just taOS Dark (the default) and taOS Light. Remove the Matrix Terminal builtin and rename Default -> taOS Dark, Light -> taOS Light. Update the theme tests that referenced matrix-terminal.
* fix(agents): show the model on every agent + align the row columns - Map the agent's model from /api/agents so every agent (not just the system agent) shows the model indicator chip. - Give the status and actions columns fixed widths so the metadata columns line up row to row; the protected system agent's 3 action icons now reserve the same column as a deployed agent's 4 (right-aligned), so nothing drifts. * fix(agents): show the model as plain text, no pill or icon Drop the chip styling and the Cpu icon from the model label; it now reads as a plain muted mono line under the framework sub-label.
phase 1) (#862) * feat(github): device-flow connect for GitHub identities in Secrets (#858 phase 1) * fix(github): dedupe identities on reconnect + RFC slow_down backoff (Gitar review) - Reconnecting an already-connected GitHub account (same login) refreshes the token in place instead of creating a duplicate identity row. - Device poll signals slow_down so the frontend increases its poll interval by 5s per RFC 8628 §3.5. Tests for both.
…tte, mobile audit, wallpaper Phase 1, island v2, GitHub phases
…863) Drop the SYSTEM AGENT group title (all three render branches) and give every card a uniform gap: the system agent gets mb-3 above the deployed list, and the deployed list is space-y-3 to match.
…acked-out elements) (#867) * fix(theme): force WebKit to repaint backdrop-filter layers on theme switch Safari keeps backdrop-filter elements (dock, top bar, modals, widgets) on cached GPU compositing layers and does not re-rasterize them when the theme custom properties on :root change at runtime. Switching dark<->light could leave those surfaces rendering black on the live screen, while screenshots looked correct because the screenshot path forces a full raster (which is also why the bug was invisible to screenshot-based testing). Drop backdrop-filter for a single frame via a [data-theme-switching] attribute set in applyThemeConfig/revertTheme, forcing WebKit to rebuild each backdrop layer against the new tokens. Imperceptible (~1 frame) and a no-op in Chrome/Firefox, which re-raster eagerly. * fix(theme): single repaint per theme apply + timer fallback for hidden tabs Addresses Gitar review on the Safari backdrop-filter repaint: - revertTheme now takes a silent flag; applyThemeConfig calls it silently and owns the single repaint after the new tokens are written, avoiding a redundant forced reflow (and an early repaint before tokens existed). - forceCompositingRepaint adds a setTimeout(250ms) fallback so the data-theme-switching attribute is always cleared even when rAF is paused on a hidden/background tab.
… (#868) * feat(theme): macOS-dark graphite palette + live neural wallpaper Retunes the taOS Dark theme off the blue-indigo base (#1a1b2e) to a neutral macOS-style graphite charcoal, and replaces the static default wallpaper with an adaptive live wallpaper component. Theme tokens (desktop/src/theme/tokens.css @theme): - shell-bg #1a1b2e -> #1d1d1f, shell-bg-deep #151625 -> #171717 - dock/top bar rgba(22,25,32,.92) -> neutral rgba(29,29,31,.92) - accent grey #8b92a3 and the traffic lights are unchanged Live neural wallpaper (NeuralWallpaper.tsx): - adaptive <canvas> of drifting nodes + proximity links over a graphite field, inspired by the original neural wallpaper but neutral. Renders at native resolution for any aspect ratio (16:10, ultrawide 32:10, mobile portrait) from one source, so no per-resolution image assets are needed. - density scales with viewport area; the loop pauses while hidden; honours prefers-reduced-motion with a static frame. - "taOS" wordmark overlay is optional, toggled in the wallpaper picker and persisted locally (default on). The toggle only shows for neural wallpapers. Wiring: - theme-store gains a wallpaper "kind" ("image" | "neural"); the new Neural (Graphite) entry is the taOS Dark default, the original neural PNG stays selectable as Neural (Classic). - Desktop.tsx and the mobile shell render the live wallpaper when active and suppress the CSS background image in that case. - Wallpaper picker shows a graphite preview swatch for neural wallpapers. Part of #865. Live wallpapers as a shareable package format + agent authoring guidelines are a follow-up feature (brainstorm next). * refactor(theme): generic wallpaper kind + slogan overlay (decouple from "neural") Per feedback: "neural" should not be the category, and the text should not be welded to it. Not all animated wallpapers with text will be neural. - Wallpaper.kind is now "image" | "animated" (was "image" | "neural"); the specific renderer is a separate `component` field ("neural" is one renderer). - The wordmark becomes a generic slogan overlay (WallpaperTextOverlay) that draws centered text above ANY wallpaper, driven by a per-wallpaper `overlayText` default + a user toggle (showOverlayText, persisted). Colour / size / style / effects use defaults for now; configurable in a follow-up. - NeuralWallpaper is now a pure renderer (no embedded text). - The picker toggle reads "Show slogan (<text>)" and only appears when the active wallpaper defines a slogan. - Wallpapers relabelled: "Graphite" (animated, slogan taOS) is the taOS Dark default; the original PNG is "Classic" (no slogan, text already baked in). * perf(wallpaper): cache gradients, drop per-link string alloc, reactive reduced-motion Addresses Gitar review on the neural wallpaper (Pi perf target): - Precompute the 3 gradients in build() and reuse them every frame instead of reallocating ~180 gradient objects/sec. - Draw links with a fixed strokeStyle + per-pair globalAlpha rather than a toFixed rgba string per pair in the O(n^2) loop; same for node fills. - prefers-reduced-motion now reacts to live OS changes via a matchMedia change listener instead of being read once at mount.
…phite (#869) The context menu, top-bar dropdown, kill-switch menu, notification toast + centre, search palette, model browser and mobile bottom nav still hardcoded the old blue-indigo base (rgba(26,27,46)/(30,31,50)/etc), so they clashed with the new macOS graphite theme. Point them at var(--color-dock-bg) (the frosted chrome token) so they match and adapt to the light theme too. Also neutralise the navy widget card + mobile app-window backgrounds (rgba(20,20,35)/(30,30,60)) to graphite, keeping the frosted alpha. Verified in a real build+preview: the desktop context menu now renders rgba(29,29,31,0.92).
…ansport + bot fixes, standing rules, rename idea, mobile PWA task
…l (transport) (#877) * feat(desktop): controller->browser command channel for agent OS control Phase 1 of the agent-OS-control transport (the linchpin for the offline agent-driven demo). The desktop subscribes to an SSE command stream and re-dispatches each command to the existing taos:open-app / taos:window receivers, so the controller (and through it the taOS agent) can open apps and drive windows on a user's desktop. - DesktopCommandBroker: per-user pub/sub, NO replay (commands are one-shot; replaying to a reconnecting desktop would re-open closed apps) - GET /api/desktop/stream (SSE, scoped to the caller's user_id) + POST /api/desktop/command (emits to the caller's own desktop only) - use-desktop-command-stream.ts re-dispatches to the existing event receivers - 8 backend + 5 frontend tests; docs/desktop-control.md updated Next: agent MCP tools (open_app/arrange + data tools) that POST commands, with the agent-manual entry, land together so the manual only advertises real capabilities. Live agent-drives-desktop visual is a Pi-verify. * fix(desktop): address bot review on command channel - CRITICAL: scope by request.state.user_id (AuthMiddleware's field), not the never-set request.state.user; prevents all callers collapsing to one shared channel (cross-user desktop control) - guard against JSON.parse returning null/non-object in the stream hook - bound per-subscriber queue (128) with drop-oldest so a stalled SSE consumer can't grow memory unbounded; +test - SSE no-cache / X-Accel-Buffering headers so proxies don't buffer commands - docs: curl example notes the session-cookie scoping
…se 2) (#878) * feat(agent): open_app + arrange_windows agent tools (agent OS control, phase 2) The two agent-facing tools that complete the agent-OS-control framework: an agent can now open an app on the user's desktop and arrange windows. Each tool just emits onto the per-user DesktopCommandBroker (phase 1, #877); the controller streams it to the browser which acts on it. Kept minimal on purpose. - tinyagentos/tools/desktop_tools.py: execute_open_app / execute_arrange_windows (scoped to the calling user via request.state.user_id — never another user) - wired into skill_exec SKILL_IMPLEMENTATIONS + seeded in skills.py (category 'desktop'); assignable to any agent - agent-manual: new 09-os-control.md + recompiled docs/taos-agent-manual.md - 6 tool tests (emit, props, scoping, validation); 27 related tests green * fix(agent): address bot review on desktop tools - refuse open_app/arrange_windows when there is no authenticated user instead of emitting to a shared 'system' bucket (Gitar) + test - backfill builtin skills on existing installs: _post_init now always runs the seed with INSERT OR IGNORE, so new desktop-control tools appear after upgrade without disturbing user-installed skills (Kilo) - agent-manual 09-os-control: drop the data-tool actions this PR doesn't implement yet so it only advertises open_app/arrange_windows (Kilo)
* style(theme): purge purple/violet/indigo from the dark theme Jay: get rid of all the purple in the dark theme. The graphite dark theme's accent token is already neutral grey; this removes the hardcoded purple-family colours still scattered across apps and swaps them for a cohesive non-purple (cyan; sky where it would collide with an existing teal sibling). - 15 app/component files: violet/purple/indigo Tailwind classes + purple hexes -> cyan - ProvidersApp: cloud badge -> sky (stays distinct from local's teal) - tokens.css: --board-accent-violet (#a78bfa) renamed -> --board-accent-cyan (#22d3ee) + the two board module.css usages updated - LEFT intentionally: the opt-in 'Deep Indigo' wallpaper preset + the accurate 'no indigo' token comments Build clean. (Pre-existing AgentsApp.test failures are unrelated + not in the CI gate.) * fix(theme): address purple-purge review (dup color + board rgba purples) - constants.ts COLORS: the 2nd #06b6d4 (was indigo #6366f1) collided with the cyan from #8b5cf6 -> distinct teal #2dd4bf (Gitar/CodeRabbit: dup key/colour) - board CSS active/focus/hover states still used rgba(167,139,250) violet (TaskCard/BoardToolbar/TaskModal) -> cyan rgba(34,211,238) (Kilo) Comprehensive scan now clean (no purple class/hex/rgba) bar the opt-in Deep Indigo name + accurate token comments. Build clean.
…, light-mode fix) (#880) * feat(messages): polish the mobile channel list (avatars, theme tokens, timestamps) The mobile Messages view (which the /chat-pwa 'taOS talk' standalone PWA mirrors 1:1, no separate build) looked plain and used hardcoded white rgba that broke in light theme. This polishes it toward a mobile Slack/Discord feel: - agent avatar per DM row (reuses MessageAvatar); Hash/Bot tile for topic/a2a - name + relative last-activity time; unread rows bold with a clear badge - all colours via scheme-aware --color-shell-* / accent tokens, so it reads correctly in BOTH light and dark (was white-on-white in light) - polished section headers + empty states via tokens Affects both the in-OS mobile Messages view and the taOS talk PWA. tsc + build clean. * fix(messages): address mobile-list review (avatar gate, ticking time, preview) - only DM channels get an agent avatar; topics/groups/a2a get a glyph tile (Hash/Users/Bot) — a topic/group can include agent members too (Gitar) - relative timestamp now passes nowMs so it refreshes on the 60s tick (Kilo) - added the lastPreview line under each row (avatar + name + preview + time) for a proper mobile Slack/Discord feel The unread badge stays a clear blue: readable in both light and dark, intentional notification accent (not part of the neutral token pass).
…/dark (#881) The standalone taOS talk PWA (/chat-pwa) only imported tokens.css and never applied the user's selected theme, so it always rendered base dark and ignored light mode. Call restoreActiveTheme() on boot, mirroring the desktop shell (App.tsx).
…l this-session PRs live
…_image) (#882) * feat(agent): project data tools (create_project, add_task, canvas_add_image) Phase 3 of agent OS control: the agent can now BUILD inside a project, not just open apps. These call the existing project/task/canvas stores in-process (the same methods the REST routes use), so effects stream live to an open Projects app via the existing project_event_broker SSE — the board fills and artwork lands while the user watches, with no new transport. Completes the storybook-demo flow (open Projects -> create_project -> add_task x N -> generate_image -> canvas_add_image). - tinyagentos/tools/project_tools.py (scoped to request.state.user_id; refuse if unauthenticated) - wired into skill_exec + seeded in skills.py (category 'projects') - agent-manual 09-os-control updated + recompiled - 8 tests (create/add/image, slugify, field validation, no-user refuse); 24 related green * fix(agent): enforce project ownership on add_task/canvas_add_image Gitar/Kilo: the tools accepted an arbitrary project_id and wrote to it without checking the caller owns it — a cross-user write. Now fetch the project and require user_id == project.user_id (or admin) before adding a task/image; refuse with 'not your project' / 'project not found' otherwise. +ownership/admin/missing tests (11 total). * fix(agent): harden project-tool arg typing (CodeRabbit) - add_task/canvas_add_image require string project_id/title/file_id - canvas_add_image validates x/y are numeric and returns a clean error
…Pi (#882, all 5 skills backfilled live)
…call leaderboard)
…l flow; 3-run leaderboard + model rec
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
👋 Thanks for the PR! This one targets See CONTRIBUTING.md for the branch model. |
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR adds desktop control and GitHub device authorization flows, expands theme and wallpaper handling, refreshes multiple desktop UI surfaces, adds workspace rename support and project tools, updates runtime/update maintenance, and revises project documentation and branding. ChangesProduct surface updates
Sequence Diagram(s)sequenceDiagram
participant SkillExec
participant DesktopAPI as /api/desktop/command
participant Stream as /api/desktop/stream
participant Browser as useDesktopCommandStream
participant Control as useDesktopControl
SkillExec->>DesktopAPI: emit open-app/window command
DesktopAPI->>Stream: enqueue user-scoped command
Stream->>Browser: SSE data event
Browser->>Control: dispatch taos:open-app / taos:window
Control->>Control: open, move, resize, arrange window
sequenceDiagram
participant SecretsApp
participant GitHubConnect
participant Backend as /api/github/oauth/device/*
participant GitHub
participant Store as GitHubIdentitiesStore
SecretsApp->>GitHubConnect: render connect panel
GitHubConnect->>Backend: start device flow
Backend->>GitHub: request device code
GitHub-->>GitHubConnect: user code and verification URL
GitHubConnect->>Backend: poll device flow
Backend->>GitHub: exchange device code and fetch user
Backend->>Store: save encrypted identity
Backend-->>GitHubConnect: connected identity
Estimated code review effort🎯 5 (Critical) | ⏱️ ~100 minutes Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
| Dashboard-icons CDN helper | ||
| ------------------------------------------------------------------ */ | ||
|
|
||
| const di = (slug: string) => |
There was a problem hiding this comment.
💡 Quality: Store icons fetched from external CDN contradicts offline goal
StoreApp/index.tsx renders app icons via a jsdelivr CDN helper (di = (slug) => https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/${slug}.png) and repo logos via github.com. The PR markets taOS as "fully offline" (agent OS control validated offline, no-cloud homelab apps), yet the redesigned Store depends on external network resources to show icons. On an air-gapped Pi every catalog/homelab icon will fail to load.
This degrades gracefully — the <img onError={() => setIconFailed(true)}> handlers fall back to a <Package/> lucide icon — so it is not a functional break, but the polished real-logo experience silently disappears offline. Consider bundling the dashboard-icons set locally (or caching via the service worker / a backend proxy) so the Store looks the same with no internet.
Was this helpful? React with 👍 / 👎
| // pending -> back off by 5s on slow_down (RFC 8628 §3.5), then poll again | ||
| if ("slow_down" in result && result.slow_down) { | ||
| intervalMs += 5000; | ||
| } | ||
| pollTimer.current = setTimeout(tick, intervalMs); |
There was a problem hiding this comment.
💡 Quality: Device-flow poll ignores GitHub-provided slow_down interval
In GitHubConnect.tsx beginPolling, on a slow_down response the client unconditionally adds a fixed 5s to its interval (intervalMs += 5000). RFC 8628 §3.5 specifies that the token-endpoint slow_down response carries a new interval value the client should adopt, and the backend device_poll does not forward GitHub's returned interval either. The fixed +5s is usually adequate, but if GitHub requests a larger backoff the client can keep polling too fast and receive repeated slow_down responses, prolonging the connect flow. Consider forwarding the interval field from the token response through device_poll and using it in beginPolling.
Was this helpful? React with 👍 / 👎
| :root[data-scheme="light"] [class~="text-white"] { color: rgba(0, 0, 0, 0.88); } | ||
| :root[data-scheme="light"] [class~="text-white/90"] { color: rgba(0, 0, 0, 0.84); } | ||
| :root[data-scheme="light"] [class~="text-white/80"] { color: rgba(0, 0, 0, 0.78); } | ||
| :root[data-scheme="light"] [class~="text-white/70"] { color: rgba(0, 0, 0, 0.68); } | ||
| :root[data-scheme="light"] [class~="text-white/60"] { color: rgba(0, 0, 0, 0.58); } | ||
| :root[data-scheme="light"] [class~="text-white/50"] { color: rgba(0, 0, 0, 0.50); } | ||
| :root[data-scheme="light"] [class~="text-white/45"] { color: rgba(0, 0, 0, 0.48); } | ||
| :root[data-scheme="light"] [class~="text-white/40"] { color: rgba(0, 0, 0, 0.45); } | ||
| :root[data-scheme="light"] [class~="text-white/35"] { color: rgba(0, 0, 0, 0.44); } | ||
| :root[data-scheme="light"] [class~="text-white/30"] { color: rgba(0, 0, 0, 0.42); } | ||
| :root[data-scheme="light"] [class~="text-white/25"] { color: rgba(0, 0, 0, 0.40); } | ||
| :root[data-scheme="light"] [class~="text-white/20"] { color: rgba(0, 0, 0, 0.40); } | ||
| :root[data-scheme="light"] [class~="text-white/15"] { color: rgba(0, 0, 0, 0.38); } |
There was a problem hiding this comment.
💡 Quality: Light-scheme inversion may reduce contrast on colored buttons
The new light-scheme compatibility layer in tokens.css globally rewrites text-white to near-black (color: rgba(0,0,0,0.88)) under :root[data-scheme="light"]. This is correct for text-white sitting on white-overlay surfaces, but it also hits text-white used as the label on saturated colored fills (e.g. a primary button with bg-emerald-500 text-white, or the red/amber chips in AgentRow). On a mid/dark colored background, dark text can drop below the WCAG contrast it had as white, harming readability in light mode. Since the inversion is class-based and unscoped, it cannot distinguish "white text on overlay" from "white text on a colored fill." Worth spot-checking colored CTAs/badges in light theme and adding explicit overrides where needed.
Was this helpful? React with 👍 / 👎
Code Review 👍 Approved with suggestions 0 resolved / 3 findingsIntegrates agent OS control framework, macOS-dark theme, and app redesigns into master. Address potential findings regarding external CDN icon fetching, GitHub device-flow polling intervals, and light-mode contrast on colored buttons. 💡 Quality: Store icons fetched from external CDN contradicts offline goal📄 desktop/src/apps/StoreApp/index.tsx:23 📄 desktop/src/apps/StoreApp/index.tsx:308 📄 desktop/src/apps/StoreApp/index.tsx:452-453 📄 desktop/src/apps/StoreApp/index.tsx:574-575 📄 desktop/src/apps/StoreApp/index.tsx:633-634 StoreApp/index.tsx renders app icons via a jsdelivr CDN helper ( This degrades gracefully — the 💡 Quality: Device-flow poll ignores GitHub-provided slow_down interval📄 desktop/src/apps/secrets/GitHubConnect.tsx:78-82 📄 tinyagentos/routes/github_oauth.py:164-168 In GitHubConnect.tsx 💡 Quality: Light-scheme inversion may reduce contrast on colored buttons📄 desktop/src/theme/tokens.css:80-92 The new light-scheme compatibility layer in tokens.css globally rewrites 🤖 Prompt for agentsOptionsAuto-apply is off → Gitar will not commit updates to this branch. Comment with these commands to change:
Was this helpful? React with 👍 / 👎 | Gitar |
| }, []); | ||
|
|
||
| useEffect(() => stopPolling, [stopPolling]); | ||
|
|
There was a problem hiding this comment.
CRITICAL: Polling cleanup effect clears timers immediately
useEffect(() => stopPolling, [stopPolling]) runs after every render. After beginPolling schedules pollTimer/expiryTimer, the next render clears them, so the device-flow poll loop will never run.
| useEffect(() => () => stopPolling(), [stopPolling]); |
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| # Identities: list / delete (NO tokens ever returned) | ||
| # --------------------------------------------------------------------------- | ||
|
|
||
| @router.get("/api/github/identities") |
There was a problem hiding this comment.
WARNING: Identity list is global across users
list_identities() returns every row in github_identities without filtering by request.state.user_id. In a multi-user install, any authenticated user can see other users' connected GitHub logins/avatars and identity ids. Store rows should include an owner user_id and list should filter by the caller.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| return await store.list() | ||
|
|
||
|
|
||
| @router.delete("/api/github/identities/{identity_id}") |
There was a problem hiding this comment.
CRITICAL: Identity deletion is not scoped to the caller
delete_identity() accepts any UUID and deletes that row globally. Any authenticated user can delete another user's connected GitHub identity because the route does not read request.state.user_id or filter the delete by owner. Add user_id to the identity schema and require WHERE id = ? AND user_id = ?.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| if dst.exists(): | ||
| return JSONResponse({"error": "Target already exists"}, status_code=409) | ||
|
|
||
| dst.parent.mkdir(parents=True, exist_ok=True) |
There was a problem hiding this comment.
WARNING: Rename can error when moving a directory into itself
The endpoint allows dst to be inside src (for example src=dir, dst=dir/nested/file). dst.parent.mkdir(...) may create the nested parent, then src.rename(dst) raises an OSError instead of returning a controlled 400. Add an ancestor check before creating parents/rename.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Code Review SummaryStatus: 4 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)CRITICAL
WARNING
Other Observations (not in diff)No additional non-diff code issues found. Files Reviewed (101 files)
Fix these issues in Kilo Cloud: https://app.kilo.ai/cloud-agent-fork/review/a996e706-437e-4e09-8e0f-95a0c5fcd623 Reviewed by nex-n2-pro:free · 5,577,457 tokens |
Promote dev to master so all users get the updates. Every commit here was individually CI'd + bot-reviewed into dev, and the whole set is deployed + verified live on the Pi.
Highlights
Agent OS control framework (new, this session) — the taOS agent can drive the desktop and build in a project, fully offline:
open_app/arrange_windows+ controller→browser command channel (feat(desktop): controller→browser command channel for agent OS control (transport) #877, feat(agent): open_app + arrange_windows tools — agent OS control (phase 2) #878)create_project/add_task/canvas_add_imagedata tools (feat(agent): project data tools (create_project, add_task, canvas_add_image) #882)window.taosDesktopprogrammatic control API (feat(desktop): programmatic desktop control API (window.taosDesktop) #874)Theme + visuals
Apps
/chat-pwatheme fix (fix(chat-pwa): apply persisted theme on boot (respect light/dark) #881)Infra/fixes
Merge method: standard merge (preserve history). Do NOT delete the dev branch.
Summary by CodeRabbit
Release Notes
New Features
open_appandarrange_windowstools.Enhancements