mirror of
https://github.com/aaif-goose/goose.git
synced 2026-07-03 14:10:03 +02:00
562deafe4dcccf5790ea233df7a0ae4e21c82c52
26 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
562deafe4d |
[codex] Archive chats and restore them from settings (#26)
* feat: add archive/unarchive session support to frontend types, API, and store Replace the delete-based archiveSession with actual archive/unarchive API calls. Add archivedAt field to Session and ChatSession types, wire up new Tauri invoke bindings, and update the Zustand store to mark sessions as archived instead of removing them. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add show more/less toggle to sidebar project and recents sections Show 3 chats by default in both project sections and recents. For ≤8 items, toggle inline expansion. For >8 items, navigate to the full projects view instead. Follows the goose-spence pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Archive chats and restore them from settings * Refresh project list after restore --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
f29cebb505 |
feat: wire up ACP session metadata and persist across restarts (#25)
* feat: surface ACP session title, model state, and session ID in UI Wire up new acp-client MessageWriter callbacks (on_session_info_update, on_model_state_update) to Tauri events and frontend listeners. Session titles and model names from ACP providers now update the sidebar, tabs, and status bar reactively. Fallback title generation from the first user message when the provider doesn't send SessionInfoUpdate. Add session ID display with copy button to the status bar. Fix doubled streaming text caused by React StrictMode double-mounting with async listener cleanup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: persist session metadata to backend across app restarts Extend the backend Session struct with provider_id, persona_id, and model_name fields. Add a generic update_session Tauri command so the frontend can write-through any metadata change to disk. The frontend chatSessionStore now persists title, provider, persona, and model on every updateSession call and restores them from the backend on load. Remove the persona-per-session hack from ui_state — persona now lives on the session itself. Hide token count in status bar when zero. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: update e2e test for removed model badge default The home screen no longer shows a hardcoded "Claude Sonnet 4" text since model info now comes from ACP. Update the smoke test to check for the persona picker ("Goose") which is always visible on the home screen. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove stale model badge e2e test The model badge test matched a hidden SVG <title>Goose</title> element instead of visible UI. The underlying feature (static model name on home screen) no longer exists — model info is now dynamic from ACP. The chat input placeholder is already covered by an existing test. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
f5c8ba168f |
feat: persona picker with @ mention support (#24)
* feat: add persona picker and @ mention support in chat Replace the provider-first model with a persona-first interaction pattern. Users now pick a Persona (with its own system prompt, default provider, and model) from a dropdown in both the home screen and chat input. Typing @ in the chat textarea opens an autocomplete to mention any persona inline, switching context for that message. Provider selection is still available as a secondary override. New components: - PersonaPicker: dropdown grouped by built-in / custom personas - MentionAutocomplete: floating autocomplete triggered by @ in textarea - ChatInputToolbar: extracted bottom bar to keep ChatInput under 500 lines - useMentionDetection: hook for detecting @ mention state in text input Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: wire persona system prompts through to ACP backend and fix mention UX - Pass persona system_prompt from frontend through Tauri to AcpService - Prepend persona instructions to user prompt in <persona-instructions> tags - Add keyboard navigation (arrow keys, Enter/Tab) to @ mention autocomplete - Fix PersonaPicker description extraction (was using index [1] instead of [0]) - Simplify ChatView handleSend by letting useChat handle system prompt injection Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: enhance persona picker with @ mentions on home screen, switch notifications, and per-message persona tracking Adds @ mention autocomplete to the HomeScreen input so users can invoke personas before starting a chat. Shows system notifications when switching personas mid-chat, and tracks which persona generated each assistant message in the timeline. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: persist persona selection across tab switches and app restarts Store the selected persona per session in ui_state.json alongside the existing tab state. When switching tabs or reopening the app, the previously selected persona is restored for each chat session. Changes: - Backend: add persona_per_session HashMap to UiState with serde(default) for backward compatibility - chatSessionStore: add personaId to ChatSession, save/restore persona mapping in persistTabState/loadTabState - ChatView: save persona changes to session store - AppShell: pass session's stored personaId to ChatView, store personaId when creating new sessions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve 4 bugs found in persona picker audit 1. Error state stuck: acpSendMessage errors now reset chatState to "idle" so the user can continue sending messages after failures. 2. Stop button cancels backend: stopGeneration now calls acp_cancel_session to terminate the Rust ACP session, preventing orphaned streaming events after the UI resets. 3. @ mention persona race condition: when switching personas via @ mention, the message send is deferred to the next render cycle so useChat picks up the new persona's system prompt instead of the stale one. 4. Deleted persona fallback: if a persisted personaId references a deleted persona, ChatView now falls back to builtin-goose (or the first available persona) and updates the session store. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: load personas eagerly at app startup Personas were only loaded when visiting the Personas page (via the usePersonas hook in AgentsView). This meant the persona picker in HomeScreen and ChatInput showed empty until the user navigated to the Personas page at least once. Now AppShell loads personas from the backend in its startup effect, alongside sessions and tab state. This ensures personas are available immediately in all views. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: fix cargo fmt in acp service Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: update tests for persona picker changes and silence clippy - Update ChatInput tests for new toolbar structure and persona props - Update HomeScreen tests to mock persona store instead of ACP providers - Add #[allow(clippy::too_many_arguments)] on send_prompt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
20f9ce4163 |
chore: bump acp-client to latest builderbot HEAD (dbd5bc9c) (#23)
Update acp-client git dependency from 17e60981 to dbd5bc9c. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
d6d58dffd3 |
feat: session persistence with tab state and sidebar recents (#22)
* feat: individual chat sessions with persistence and tab management Add full chat session lifecycle — create, switch, persist, and restore individual chat sessions backed by ACP. Key capabilities: - Session persistence: messages saved to per-session directories, metadata consolidated in ~/.goose/sessions/metadata.json - Tab state management: Zustand-based chatSessionStore with tab open/close/reorder/activate, persisted to ~/.goose/ui_state.json - Session restoration: historical messages loaded lazily from backend on tab select; tab state restored and validated on app launch - Sidebar recents: all sessions shown sorted by updatedAt, with visual distinction between open and background sessions - ACP integration: multi-agent support via acp-client, provider selector in chat and home views - UI foundations: skills/personas pages, projects sidebar, settings fixes, dev icons, chat components, and visual polish Also includes earlier PR work: sidebar navigation, ACP client, Tauri icon, dependency updates, and various bug fixes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: fix Rust formatting in session and UI state commands Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve code review issues in session persistence and UI - Fix race condition: acquire mutex in get_messages to prevent reading partially-written message files during concurrent add_message calls - Log errors in save_metadata/save_messages instead of silently discarding them, aiding diagnosis of disk/serialization failures - Refactor AppShell mount effect from nested .then() to async IIFE - Use Map for O(1) session lookups in tab derivation - Only remove session from local store on successful backend delete in archiveSession to avoid stale entries on failure - Add proper exhaustive deps to ChatView initial message effect, guarded by ref to maintain mount-only semantics Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
1b628a56cb |
feat: add doctor health-check UI and backend to preferences dialog (#21)
* feat: add doctor health-check backend commands * feat: add doctor health-check UI to preferences dialog Port the doctor feature frontend from staged into React components that match goose2's patterns (Tailwind CSS, lucide-react, cn() utility). New files: - src/shared/api/doctor.ts: Tauri API bindings for run_doctor and run_doctor_fix commands - src/features/settings/ui/DoctorCheckRow.tsx: Individual check row component with status icons, fix command dialog, and external link support - src/features/settings/ui/DoctorSettings.tsx: Doctor panel with auto-run on mount, re-run button, copy debug report, and tool/agent section grouping Modified: - src/features/settings/ui/SettingsModal.tsx: Add Doctor tab with Stethoscope icon between Appearance and General nav items * fix: add right padding to doctor header to avoid overlap with close button The Re-run and Copy details buttons in the Doctor settings panel were rendered behind the modal's X close button due to insufficient clearance. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: align doctor panel heading and nav position with other settings panels Remove the inline Stethoscope icon from the Doctor heading to match the plain h3 style used by all other settings panels. Move the Doctor nav item to sit between Projects and About in the sidebar. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: refresh ACP providers after doctor checks and fixes After running doctor checks or applying a fix, call discoverAcpProviders() so newly-installed agents appear in the agent selector without requiring an app reload. This matches the Staged implementation where DoctorSettingsPanel.svelte calls refreshProviders() after runChecks(). Add a runChecksAndRefresh wrapper that awaits runChecks() then calls discoverAcpProviders(), guarded by the existing mountedRef check. Use it in all three call sites: useEffect on mount, Re-run button onClick, and the onFixed callback passed to DoctorCheckRow. * fix: use Tauri opener plugin instead of window.open for external URLs Replace window.open(url, '_blank') with openUrl() from @tauri-apps/plugin-opener in DoctorCheckRow. In a Tauri webview, window.open is unreliable for opening URLs in the system browser. The opener plugin uses the native OS handler and is already configured in the Tauri backend (opener:default capability). - Add @tauri-apps/plugin-opener as a frontend dependency - Import openUrl from @tauri-apps/plugin-opener - Replace window.open(check.fixUrl, '_blank') with void openUrl(check.fixUrl) * fix: use ID-based fix execution instead of passing shell commands over IPC The frontend previously sent raw shell command strings to the backend's run_doctor_fix handler, which would execute them directly. This is a security concern as the IPC boundary should not accept arbitrary commands. Now the backend is the single source of truth for fix commands. The frontend sends only a check ID and fix type ("command" or "bridge"), and the backend looks up the corresponding command from the static AgentCheckInfo definitions or hardcoded tool check commands. Unknown IDs or fix types are rejected with an error. - Add fix_type field to DoctorCheck struct (set alongside fix_command) - Add lookup_fix_command() that maps check_id + fix_type to a command - Rewrite run_doctor_fix to accept (check_id, fix_type) instead of a raw command string - Update frontend API and DoctorCheckRow to pass check.id + check.fixType Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve doctor code review comments - Replace stringly-typed fix_type (Option<String>) with a FixType enum on both backend and frontend, making invalid states unrepresentable and eliminating the wildcard fallback in lookup_fix_command - Collapse duplicate "not installed" fallback branches in check_agent_install into a single branch that conditionally appends the main-binary search output - Align fix confirmation dialog with existing dialog patterns: add role="dialog", aria-modal, aria-label, Escape key handler, and match the class ordering used by other confirmation dialogs in the codebase Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
bffcea2823 |
feat: use acp-client from builderbot repo as git dependency (#20)
* feat: use acp-client from builderbot repo as git dependency Remove the local acp-client crate (crates/acp-client/) and replace it with a git dependency pointing to block/builderbot on the main branch. The builderbot version is a strict superset of the local copy — same public API (AcpDriver, AgentDriver, MessageWriter, Store, discover_providers) plus remote workspace support, concurrent provider discovery, structured logging, and graceful shutdown. Changes: - Remove 'crates/acp-client' from workspace.members in Cargo.toml - Replace path dependency with git dependency (block/builderbot, main) - Delete src-tauri/crates/acp-client/ directory (5 files, ~1640 lines) - Verified cargo check passes with no code changes needed in goose2 * fix: pin acp-client to rev and clean up config - Pin acp-client git dependency to rev 5af819e instead of branch=main for reproducible builds - Remove redundant single-member [workspace] table from Cargo.toml - Remove deprecated baseUrl from tsconfig.json (TS 5.9+ deprecation) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: update acp-client pin to latest merge commit Pin acp-client to rev 17e6098 (builderbot PR #554 merge commit) to pick up the latest acp crate changes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
cf68533896 |
feat: add branch-based dev icons and stable ports for worktree disambiguation (#19)
* feat: add branch-based dev icon for worktree disambiguation Add a Swift script that generates a modified .icns file with a blue badge containing the current branch name. When running in a git worktree, the `just dev` and `just dev-debug` recipes automatically detect this and generate a badged icon, making it easy to distinguish between multiple dev instances in the dock. - scripts/generate-dev-icon.swift: Generates badged icons with text wrapping on hyphens, multi-size iconset generation via iconutil - justfile: dev and dev-debug recipes now detect worktrees and pass icon override config to Tauri via --config JSON merge - Generated icons go to src-tauri/target/dev-icons/ (already gitignored) * feat: derive stable dev port from working directory for worktree disambiguation Each worktree gets a stable, unique port derived from the SHA-256 hash of the working directory path (range 10000-64999). This prevents port conflicts when running multiple dev instances simultaneously. - justfile: dev and dev-debug recipes compute VITE_PORT and pass it via --config JSON merge to override devUrl and beforeDevCommand - vite.config.ts: server port and HMR port read from VITE_PORT env var, falling back to 1520 for standalone frontend dev (just dev-frontend) - Icon config in dev recipe now merges into existing TAURI_CONFIG via python3 JSON manipulation instead of replacing it - Icon config in dev-debug recipe appends a separate --config flag |
||
|
|
dc516fdb19 |
feat: add ACP provider selector to chat and home (#18)
* feat: replace mode selector with ACP provider selector in chat input Replace the placeholder mode selector (agent/ask/plan) with a functional provider selector that discovers available ACP providers at runtime and routes messages through the selected provider. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: derive chat agent name from selected provider Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: update HomeScreen tests for provider selector Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use flexible placeholder matcher in e2e smoke test The Home page placeholder now reflects the selected ACP provider name instead of hardcoded "Goose". Use a starts-with selector so the test passes regardless of which provider label is shown. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
8c3471f43f |
Fix settings page (#17)
* fix: repair broken settings modal layout The <nav> element with settings navigation buttons was a sibling of the sidebar div instead of being nested inside it, and the main flex container was missing its closing tag. This broke the sidebar/content flex layout. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: restore missing padding wrapper around Settings title The merge in #15 dropped a wrapper div with px-4 py-4 padding and entrance animation around the "Settings" heading, causing it to be smashed against the top-left corner of the sidebar. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: consolidate types and stores into feature-sliced architecture Removed root-level src/types/ and src/stores/ directories that contained outdated duplicates of types and unused store implementations. Moved unique config types (AgentConfig, Skill, Provider, Model) to src/shared/types/config.ts. Relocated stores to their owning features (agentConfigStore → agents, sessionStore → chat, skillStore → skills). Deduplicated ChatState, TokenState, and Session types — src/shared/types/chat.ts is now canonical. Updated AGENTS.md with clear guidelines on where types and stores should live. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
c7ec58f660 |
refactor: remove unused root-level stores and types (#16)
The root /src/stores/ and /src/types/ directories contained dead code that was superseded by feature-level stores and /src/shared/types/. None of these files were imported anywhere in the active codebase. Removed: - src/stores/ (agentConfigStore, chatStore, sessionStore, skillStore) - src/types/ (chat.ts, index.ts) Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
a1893bb184 |
feat: add projects feature to sidebar (#15)
* feat: add projects backend and frontend foundation
- Rust backend: CRUD for projects stored at ~/.goose/projects/{slug}/project.json
- Frontend: API layer, Zustand store, CreateProjectDialog, ProjectsView
- Project model: name, description, prompt, icon, color, preferredProvider/Model, workingDir, useWorktrees
- Tab type extended with optional projectId
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: redesign sidebar with projects + chats hierarchy
Replace the "Recent" section with a goose-spence-style layout:
- Projects section with collapsible groups and nested chats
- Standalone chats section for sessions not in any project
- Remove "Projects" from top nav items (now in sidebar body)
- Extract SidebarProjectsSection to stay under file size limit
- Wire AppShell to pass project data and callbacks to Sidebar
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add [+] button to PROJECTS header in sidebar
- PROJECTS section always visible (even with no projects)
- [+] button on PROJECTS header opens CreateProjectDialog
- Wire onCreateProject through Sidebar → AppShell
- CreateProjectDialog rendered in AppShell, refreshes project list on create
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: simplify project dialog and use color dots
- Remove Description field (Prompt serves as description)
- Hide Icon field (always uses default)
- Remove Preferred Model field
- Replace Provider text input with ACP provider dropdown
- Add Browse button for Working Directory (with Tauri dialog fallback)
- Show color dots instead of emoji icons in sidebar and project cards
- Show prompt preview in project cards instead of description
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: always-visible create project button and 3-dot menus
- Make [+] create project button always visible (not hover-only)
- Match button size/alignment with "New chat" buttons
- Add 3-dot menus (Edit/Archive) to project headers
- Add 3-dot menus (Edit/Archive) to chat items (nested + standalone)
- Menus appear on hover, close on outside click
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: fix alignment, edit project dialog, browse button, menu behavior
- Align [+] create project button with project row [+] buttons (px-1.5)
- Wire "Edit" on project menu to open CreateProjectDialog with project data
- Chat menus now only show "Archive" (removed Edit)
- Install tauri-plugin-dialog for native folder picker (Browse button)
- Add dialog:allow-open to Tauri capabilities
- Fix 3-dot menus staying visible: force opacity when dropdown is open
- Remove unused onEditChat prop
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: always-visible 3-dot menus and tighter header alignment
- Make 3-dot menus always visible at 60% opacity (not hover-dependent)
- Remove mr-1 from PROJECTS header [+] button to reduce right gap
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: proper hover behavior for 3-dot menus and header alignment
- Restore hover show/hide for 3-dot menus with open-state override
- When dropdown is open, force trigger button visible (opacity-100)
- When closed, standard group-hover behavior applies
- Fix header [+] alignment: remove container px, use pl on text + mr-1 on button
- Both PROJECTS header [+] and project row [+] now have identical right offset
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: auto-expand project when creating a new chat in it
When the active tab changes to one inside a project, automatically
expand that project in the sidebar so the new chat is visible.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: resolve pre-push lint issues
- cargo fmt: fix Rust formatting in projects.rs
- clippy: allow too_many_arguments on create_project and update_project
- biome: replace non-null assertions with local variable in Sidebar.tsx
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: wire archive actions and add project ordering
- Archive project: deletes from filesystem and refreshes sidebar
- Archive chat: closes the tab and cleans up session
- Add `order` field to ProjectInfo (auto-assigned on create, preserved on update)
- Projects sorted by order instead of alphabetically
- Backwards-compatible: existing projects without order default to 0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: consistent hover show/hide for [+] and 3-dot buttons
Use invisible/visible + opacity combo for both ItemMenu trigger and
[+] new chat button. The invisible class provides reliable show/hide
while opacity handles the visual transition. Both now appear and
disappear in sync on group hover.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: soft-delete archive for projects with restore in settings
- Add archivedAt field to ProjectInfo (null = active, timestamp = archived)
- list_projects filters out archived; new list_archived_projects returns only archived
- archive_project sets archivedAt timestamp; restore_project clears it
- Archive action in sidebar now soft-deletes instead of hard-deleting
- Settings modal shows "Archived Projects" section with Restore and Delete buttons
- Delete permanently option available for true removal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: move archived projects to dedicated Projects tab in settings
Add a "Projects" tab to the settings modal with the FolderKanban icon.
Archived projects section moved from General to its own tab for
cleaner organization.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add confirmation dialog for permanent project deletion
Clicking "Delete" on an archived project in Settings now shows a
confirmation dialog before permanently removing the project.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
e2fa4e8619 |
fix: prevent horizontal scrolling in sidebar nav (#14)
When overflow-y is set to auto, browsers implicitly set overflow-x to auto as well, creating an unwanted horizontal scrollbar. Explicitly set overflow-x-hidden on the sidebar nav element. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
c6739f6327 |
fix: settings modal X button not dismissing dialog (#13)
The content div overlapped the absolutely-positioned close button, intercepting click events. Adding z-10 ensures the button stays above the content layer. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
5b1a8ba0c3 |
feat: add ACP client integration for multi-agent support (#12)
* feat: add ACP client integration for multi-agent support Port the acp-client crate from builderbot and integrate it into the goose2 Tauri app. This enables connecting to ACP-compatible agents (Goose, Claude Code, Codex, Pi, Amp) over stdio. Rust backend: - acp-client crate: AcpDriver, MessageWriter/Store traits, agent discovery, session management with replay, !Send workaround - services/acp.rs: TauriMessageWriter (streams via events), TauriStore (session persistence), AcpService - commands/acp.rs: discover_acp_providers, acp_send_message Frontend: - api/acp.ts: provider discovery + message sending - useAcpStream.ts: Tauri event listener for streaming responses Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: wire ACP chat flow with default Goose agent - Create default Goose ACP agent on first launch (auto-selected) - Replace mock chat with real ACP routing in useChat - Enable useAcpStream in ChatView for streaming responses - Add 13 tests for ACP streaming + default agent creation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: nested button hydration error and streaming text accumulation - TabBar: restructure tab as div[role=tab] with span close target to eliminate button-inside-button HTML violation - useAcpStream: accumulate text chunks in a ref before passing to updateStreamingText, so the full text is displayed instead of only the last chunk - useChat: remove unused biome suppression comment Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve three critical ACP messaging bugs 1. Parameter name mismatch: use snake_case keys in Tauri invoke to match Rust function parameter names 2. Premature cleanup: don't clear streamingMessageId in finally block — acpSendMessage returns immediately (Rust runs in bg), let useAcpStream handle cleanup on acp:done event 3. Timing race: enable useAcpStream when streamingMessageId is set (not chatState), so listener is active before events arrive Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve three ACP streaming bugs - Use camelCase params in acp_send_message invoke (Tauri 2 default) - Always enable useAcpStream listener to avoid missing events - Clear streamingMessageId on non-abort errors to unstick UI Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: extract duplicate findLastIndex to shared utility Both chatStore.ts and useChat.ts had identical findLastIndex helper functions. Extracted to src/shared/lib/arrays.ts following the existing shared/lib pattern (cn.ts). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove binaryPath from AcpProvider, rewrite hook tests - Remove binaryPath from AcpProvider interface (backend only sends id/label) - Rewrite useAcpStream tests to mock Tauri listen() and use renderHook() - Tests now verify actual hook behavior: event dispatch, session filtering, text accumulation, cleanup on unmount, enabled flag Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add markdown rendering and fix UI spacing to match goose-spence Add MarkdownContent component with syntax highlighting, GFM support, and copy-to-clipboard on code blocks. Update MessageBubble, ThinkingBlock, and MessageTimeline to use markdown rendering and proper spacing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: correct inline code detection for react-markdown v9 and add dark mode prose support Remove deprecated `inline` prop and detect block code via language class or newline content. Add `dark:prose-invert` so prose text is readable in dark mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add AcpSessionRegistry for robust process lifecycle management Prevents dangling `goose acp` processes by tracking running ACP sessions with CancellationTokens, cancelling all on app exit, and cleaning up stale session files on startup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: fix cargo fmt formatting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
fde43f3038 |
Replace default Tauri icons with Goose app icon (#11)
* Replace default Tauri icons with Goose app icon Copied the goose silhouette icon from the goose desktop app into all Tauri icon slots (macOS, Windows, iOS, Android) so the app displays the correct brand icon. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add proper padding to app icon for correct dock sizing The icon was filling the entire canvas edge-to-edge, making it appear ~25% larger than other apps in the dock and Alt+Tab bar. Added ~10% transparent padding on each side following Apple's icon guidelines. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
3b8baf07e3 |
fix: persona & skill dialog layouts + drag-and-drop on new cards (#9)
* fix: persona & skill dialog layouts + drag-and-drop on new cards Restructure PersonaEditor and CreateSkillDialog to use fixed header/footer with a scrollable middle area so action buttons stay visible. Add useFileImportZone hook and wire drag-and-drop file import onto the "New Persona" and "New Skill" cards. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: update SkillsView empty state text assertion Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
a088b17b80 |
feat: personas & skills — rename, import/export, creation, and layout fixes (#8)
* feat: personas, skills, and import/export improvements
- Rename "Agents" to "Personas" across the UI (sidebar, headings, descriptions)
- Load markdown persona files from ~/.goose/agents/ on startup with periodic
refresh (60s interval + window focus), parsed from YAML frontmatter + body
- Implement persona import/export matching sprout's .persona.json v1 format
with export from card menu and import via file picker
- Implement "New Skill" creation dialog with kebab-case validation, writing
SKILL.md files to ~/.goose/skills/{name}/
- Add backend path traversal protection for skill name validation
- Fix persona creation to persist through backend API (was local-only)
- Fix import to refresh from backend instead of creating store duplicates
- Disable delete button for disk-loaded personas in the UI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add edit, duplicate, export, and import for skills
- Add update_skill backend command to edit existing SKILL.md files
- Add export_skill command returning sprout-compatible .skill.json format
- Add import_skills command with file validation and name collision handling
- Convert CreateSkillDialog to support edit mode (read-only name, pre-filled fields)
- Add dropdown menu on skill cards with Edit, Duplicate, Export, Delete
- Add Import button with file picker on Skills page
- Duplicate generates unique {name}-copy suffix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: make skills and personas pages fill full height with proper scrolling
Both pages now use flex column layout with h-full to fill the parent
container, and an inner scrollable wrapper with overflow-y-auto for
content overflow.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style: fix cargo fmt and clippy warnings
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: delete persistence, confirmation dialogs, and export notifications
- Fix persona deletion to persist via backend API (was local-only)
- Add delete confirmation dialog for both personas and skills
- Show export notification toast with filename after successful export
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: hide delete option for built-in and disk-loaded personas
Instead of showing a disabled delete button, hide it entirely for
personas that can't be deleted (built-in and markdown-loaded).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: update PersonaCard test for hidden delete on built-in personas
The delete menu item is now hidden (not disabled) for built-in and
disk-loaded personas, so the test checks it's absent rather than disabled.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add comprehensive tests for skills and persona features
- CreateSkillDialog: 17 tests (rendering, name validation, edit mode, form submission)
- SkillsView: 11 tests (rendering, search, card menu, delete confirmation)
- usePersonas hook: 6 tests (loading, CRUD, refresh)
- Agents API: 3 tests (export, import, refresh invoke calls)
Total test count: 100 → 137
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
aed88d7242 |
chore(deps): update actions/cache action to v5 (#6)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> |
||
|
|
cca7907ef3 |
feat: chat experience preparation — UI components, stores, and goose2.0 visual match (#7)
* feat: chat experience preparation — UI components, stores, and goose2.0-style chat input Add chat and agent management UI infrastructure without ACP protocol implementation: - Rich chat UI: ChatInput (matching goose2.0 design with mode/model/folder pickers), MessageBubble, MessageTimeline, StreamingIndicator, ThinkingBlock, ToolCallCard - Agent/Persona management: PersonaCard, PersonaEditor, PersonaGallery, AgentConfig - Zustand stores for chat state, agent state, session management - Rust backend: persona CRUD, session storage, sidecar management commands - Shared UI primitives: DropdownMenu, Tooltip, Popover (Radix UI) - Type system for messages (text, images, tool calls, thinking, reasoning) - Fix Agents page spacing to match Skills page layout Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: match goose2.0 visual design — theme colors, message styling, and UI polish - Update theme colors to pure monochrome (remove blue-gray tint) matching goose2.0 - Restyle MessageBubble: remove bubble backgrounds, right-align user messages, smaller avatars, dimmed agent text, hover-reveal actions - Restyle ToolCallCard as compact inline pills with status colors and elapsed time - Restyle ThinkingBlock with brain icon circle and left-border content indent - Fix tab close button right padding (px-3 → pl-3 pr-1.5) - Replace hardcoded "WB" initials with generic User icon in sidebar Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve Rust fmt and clippy dead_code warnings for CI Allow dead_code on preparation types/methods that will be wired up when ACP integration lands. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use getByPlaceholderText in E2E test for chat input The placeholder text is an HTML attribute, not visible text content, so getByText doesn't find it. Switch to getByPlaceholderText. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use CSS selector for placeholder text in E2E smoke test getByPlaceholderText is not available in this Playwright version. Use locator with attribute selector instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
e6750f0d95 |
chore(deps): update all non-major dependencies (#5)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> |
||
|
|
ea7d712cf0 |
feat: add Skills and Agents pages with sidebar navigation (#4)
- Add SkillsView and AgentsView stub pages matching goose2.0 layout (title left, action button right, search bar, empty state) - Add MainPanelLayout shared component for page layout - Add SearchBar shared component for page-level search - Add page-transition CSS animation (matching goose2.0) - Add storage path constants (~/.goose/) - Wire up sidebar nav items (Agents, Skills) with view routing - Add AppView type and view state management to AppShell - Sidebar active state uses subtle bg-background-secondary treatment |
||
|
|
efec8897d2 |
feat: port floating sidebar from goose2.0 (#3)
* feat: port floating sidebar from goose2.0 - Rewrite Sidebar.tsx with floating panel design (backdrop blur, rounded corners, shadow) - Smooth collapse/expand animation (48px ↔ 240px) with staggered label transitions - Search bar morphs between icon-only and full bar with ⌘K badge - Nav items with staggered fade-in animation delays - Collapsible recent chats section - User avatar footer as settings trigger - GooseIcon SVG in header (replaces emoji) - Update AppShell layout: sidebar wrapped in padding div for floating effect - Add ⌘B keyboard shortcut for sidebar toggle - All color tokens mapped to goose2 design system * fix: add missing GooseIcon and GooseLogo files * fix: remove duplicate sidebar toggle, fix traffic lights on blur - Remove PanelLeft sidebar toggle from TabBar (sidebar has its own toggle) - Add solid background behind macOS traffic light area so window controls remain visible when the window loses focus - Clean up unused onSidebarToggle prop from TabBar/AppShell * fix: make TabBar fully opaque so macOS traffic lights stay visible on blur The previous fix added a solid background div behind the traffic light area, but it rendered within the semi-transparent parent context (bg-background/80 backdrop-blur-sm). The OS compositor still saw transparency and hid the traffic lights on window blur. Simply making the TabBar background fully opaque fixes this properly. * fix: clean up nav items, subtle ⌘K badge, remove backdrop-blur for traffic lights - Nav items: keep only New Chat, Agents, Skills (removed Tasks, Artifacts, Apps) - ⌘K badge: lighter text color (foreground-secondary/40), no background - Sidebar: remove backdrop-blur-xl and make bg fully opaque — fixes macOS traffic lights disappearing on window blur * fix: improve sidebar border contrast in dark mode In dark mode, border-primary (#3f434b) and background-secondary (#3f434b) are identical, making sidebar dividers and the search border invisible. Switched all internal sidebar borders/dividers to border-secondary (#525b68) which provides clear contrast against the sidebar background in both themes. * fix: align dark mode palette with goose2.0 Updated dark mode color tokens to match goose2.0's much darker palette: - background-primary: #22252a → #0d0d0d (near black, was too light) - background-secondary: #3f434b → #141414 (sidebar, card-like) - background-tertiary: #474e57 → #262626 (muted surfaces) - Borders, text, and ring colors adjusted accordingly - This also fixes the dark mode border visibility issue since border-primary (#262626) is now distinct from background-secondary (#141414) * fix: revert custom traffic light code, rely on Tauri's built-in trafficLightPosition The custom Rust code that called setHidden:NO on focus events was interfering with Tauri's native traffic light positioning, causing them to shift down. Removed the custom code entirely — Tauri's trafficLightPosition config in tauri.conf.json handles positioning correctly on its own. |
||
|
|
70acf22cb8 |
feat: scaffold Goose2 desktop app with full UI and testing infrastructure (#2)
* feat: scaffold Tauri + React app with window dragging and app icon Sets up the goose2 desktop app with: - Tauri 2 + React 19 + Vite + Tailwind CSS - Custom titlebar with drag-to-move and double-click maximize/restore - Window state persistence via tauri-plugin-window-state - App icon ported from goose-desktop (cyan/amber yin-yang design) - Theme system with dark/light/system modes - Hermit toolchain (node, pnpm, biome, just, lefthook) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add app shell layout with tabs, sidebar, and status bar Adds the main application layout ported from goose2.0's visual design: - TabBar with session tabs, home button, and sidebar toggle - Collapsible sidebar with smooth width transition - Status bar with model name, token count, and status indicator - AppShell component wiring everything together Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add settings modal with theme section + quality fixes Settings: - Settings modal with sidebar nav (Appearance, General, About) - Theme selector (Light/Dark/System) wired to ThemeProvider - Accent color picker and density selector (visual placeholders) - Open via Cmd+, or Settings button in sidebar Quality fixes: - Fix stale state bug in tab close handler - Fix unreachable useTheme guard, add OS theme change listener - Improve accessibility (ARIA roles, labels, semantic elements) - Add prefers-reduced-motion support - Extract shared Tab type to features/tabs/types.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove references to nonexistent theme-tokens module The previous commit introduced imports for a theme-tokens module that doesn't exist. Remove those imports and define the needed types locally in ThemeProvider. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: wire up accent colors and density, add AGENTS.md Theming: - ThemeProvider now manages accent color and density (persisted to localStorage) - Accent color applied via --color-accent CSS variable on :root - Density applied via --density-spacing CSS variable (multiplier) - AppearanceSettings uses ThemeProvider context instead of local state - Tailwind config maps accent color variable - Settings modal animations enhanced to match goose2.0 reference - Component classes updated to use semantic token names Documentation: - AGENTS.md captures all project conventions, patterns, and decisions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: replace ambiguous Tailwind arbitrary durations with config values Add duration-400 and duration-600 to Tailwind config to avoid ambiguous class warnings from arbitrary value syntax. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: sidebar minimizes to icon strip instead of hiding The sidebar now shrinks to a 48px icon-only column when toggled, instead of disappearing completely. Icons stay visible with tooltips, labels and section headers are hidden. Smooth width transition. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: improve settings button alignment and styling in sidebar Match goose2.0's footer pattern with proper padding, full-opacity border, flex alignment, and smooth transition between states. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add home screen with clock, greeting, and hidden status bar Home screen shows a live digital clock, time-based greeting, and placeholder chat input. Status bar hides when on the home view (no active tab), matching goose2.0's clean home experience. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: improve home screen to match goose2.0, add chat view Home screen: large mono clock with AM/PM, time-based greeting, goose2.0-style chat input (rounded-2xl, shadow-lg, model badge). Chat view: input at bottom with scrollable messages area. Home vs chat differentiated by active tab state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: chat view now fills the full available height Remove flex from main element so child components can properly resolve h-full against the block parent. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add testing infrastructure (Vitest, Playwright, CI) Testing: - Vitest for unit/component tests with jsdom + React Testing Library - 13 tests across 3 test files (ThemeProvider, cn utility, HomeScreen) - Playwright for E2E smoke tests (4 tests) - Test setup with matchMedia mock for jsdom Tooling: - Just targets: test, test-watch, test-coverage, test-e2e - Lefthook pre-push now runs unit tests - CI gate includes tests CI/CD: - GitHub Actions workflow with 4 jobs: lint, test, desktop, rust-lint - Playwright artifacts uploaded on failure - Rust caching for faster builds Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve all Biome formatting and lint issues Auto-format all files with Biome. Fix lint issues: - Add type="button" to all interactive buttons - Replace span[role=button] with proper button element - Add dialog role to settings modal - Biome-ignore for standard accessibility !important pattern All checks pass: pnpm check, pnpm test, pnpm build. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: add src-tauri/target/ to .gitignore Prevent Rust/Tauri build artifacts from being committed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: exclude Tauri generated schemas from Biome formatting * chore: update .gitignore for full project coverage Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: pin CI actions to commit SHAs for Semgrep compliance Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve CI failures and improve lefthook auto-formatting - Fix dtolnay/rust-toolchain action SHA (was invalid, causing all Rust CI jobs to fail) - Fix Biome folder ignore pattern (remove trailing /**) - Update lefthook pre-commit to auto-format with biome instead of just checking Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use vite preview directly with explicit host for E2E server The Playwright webServer was using `pnpm preview --port 4173` which invoked vite preview without --host, causing it to bind to localhost (IPv6 ::1) instead of 127.0.0.1. This caused ERR_CONNECTION_REFUSED in CI and locally. Switch to npx vite preview with --host 127.0.0.1 and --strictPort to ensure reliable binding. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: gracefully handle non-Tauri browser environment Check for Tauri runtime before calling window APIs so the app renders correctly in browser-based E2E tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: make E2E smoke tests more robust with longer timeouts - Add 10s timeout for element visibility (CI can be slow to render) - Use .first() for model badge to handle multiple matches - Fix strict mode violation for duplicate text matches Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: smooth transition for status bar show/hide Status bar now slides and fades in/out with a 300ms transition instead of appearing/disappearing abruptly when switching views. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use dynamic import for Tauri API to prevent browser crash Static import of @tauri-apps/api/window fails at module load time in non-Tauri environments. Use dynamic import() guarded by __TAURI_INTERNALS__ check so the app renders in Playwright. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use python http.server for E2E tests, start with empty tabs Switch Playwright webServer from npx vite preview to python3 http.server for more reliable static file serving in CI. Start app with no tabs open (home screen by default). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: align E2E setup with Sprout's proven configuration - Use url instead of port for webServer readiness check - Remove -b 127.0.0.1 flag from python http.server command - Add explicit cwd to webServer config - Use pnpm exec instead of npx for Playwright in CI Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: remove unused @tauri-apps/plugin-opener JS dependency The Rust-side tauri-plugin-opener is still registered, but the JS binding package was never imported from frontend code. Removing it keeps the dependency list honest. Dark mode colors already match goose2.0 — no changes needed there. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
c4c3728da7 | prepare repo template | ||
|
|
afe8ca67cd | Initial commit |