port goose2 chat attachments into goose#8534
Conversation
* feat: add file and folder chat attachments * chore: fix rust test formatting
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf5e0cf3b3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: tulsi <tulsi@block.xyz>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 76c808576b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: tulsi <tulsi@block.xyz>
Signed-off-by: tulsi <tulsi@block.xyz>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bbacc3e864
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: tulsi <tulsi@block.xyz>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 20100e6630
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: tulsi <tulsi@block.xyz>
Signed-off-by: tulsi <tulsi@block.xyz>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5cb0906af4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| path: attachmentPath.path, | ||
| mimeType: image.mimeType, | ||
| base64: image.base64, | ||
| previewUrl: pathToPreviewUrl(attachmentPath.path), |
There was a problem hiding this comment.
Use an attachment preview source that bypasses asset scope
Path-based image attachments now set previewUrl with convertFileSrc(attachmentPath.path), but the app’s asset protocol scope is limited to the avatars directory, so files dropped/selected from normal project paths cannot be rendered through asset:// URLs. In practice, users can attach and send these images, but the thumbnail/lightbox preview is broken for most local files even though readImageAttachment already fetched usable bytes.
Useful? React with 👍 / 👎.
| // When images are present with no text, pass a single space so the ACP | ||
| // driver doesn't send an empty text content block that goose rejects. | ||
| const acpPrompt = text.trim() || (images?.length ? " " : text); | ||
| const attachmentPromptPreamble = |
There was a problem hiding this comment.
regarding the comment above this, does something need to change in the goose agent loop to accept these without this additional text?
There was a problem hiding this comment.
I don’t think anything needs to change in the Goose loop for this PR. The attachment flow now always prepends a non-empty Attached items: preamble, so attachment-only sends no longer rely on that fallback space to avoid an empty text block. At this point the " " looks redundant rather than functionally necessary, so I’d treat removing it as cleanup.
|
Looks good to me, note that this will be wired up differently once we have moved to having JS talk ACP+ directly. But this just increases the surface area of that migration a bit, and doesn't make it more complicated |
…rning * origin/main: move agent skills to repo root for tool discoverability (#8535) port goose2 chat attachments into goose (#8534) chore(release): bump version to 1.31.0 (minor) (#8527) feature: provider & model config (#8515) Move goose2 (#8516) feat: onboarding UX for the TUI (#8513) Set MACOSX_DEPLOYMENT_TARGET=12.0 in build-cli.yml (#8525) Improve local inference settings and model downloader (#8467) Add prompt injection mitigation logging back (#8518) feat(providers): add llama-swap declarative provider (#8462) fix: Unable to Run `goose update` on Linux (#8465) Add vision/image support for local inference models (#8442)
Category: new-feature
User Impact: Users can now attach files, folders, and images to Goose 2 desktop chats in this repo, with the follow-up loading and path-dedupe fixes included.
Problem: Goose 2 was ported into this monorepo before the original attachment PRs fully landed here, which risked losing desktop chat support for file and folder attachments and the hardening fixes that followed. Without this port, the new desktop app would miss mixed attachment intake, reliable attachment-only chat behavior, and the follow-up safeguards around picker errors, path dedupe, and oversized images.
Solution: This branch ports the full Goose 2 attachment feature into
ui/goose2and carries over the follow-up fixes from the old repo. The result keeps the original attachment UX intact while preserving the later reliability work for platform-aware dedupe, guarded image loading, and deterministic attachment error handling.File changes
ui/goose2/scripts/check-file-sizes.mjs
Raises the size-budget exception for the expanded desktop system command surface. This keeps the file-size guard aligned with the new attachment helpers and follow-up hardening.
ui/goose2/src-tauri/Cargo.lock
Captures the Rust dependency updates needed for attachment inspection and local image loading. This keeps the Tauri backend reproducible after the port.
ui/goose2/src-tauri/Cargo.toml
Adds backend crates for attachment MIME inspection and base64 image handling. These dependencies support path-based attachment intake from the desktop app.
ui/goose2/src-tauri/src/commands/system.rs
Adds attachment-path inspection and local image loading commands for files, folders, and images. It also includes the follow-up platform-aware dedupe logic and the 20 MB guard for path-based image encoding.
ui/goose2/src-tauri/src/lib.rs
Registers the new attachment-related Tauri commands with the app. This wires the frontend attachment flow into the native backend.
ui/goose2/src-tauri/src/services/acp/manager/session_ops/prompt_ops.rs
Builds ACP content blocks so image blocks are sent before the prompt text. This preserves correct mixed-attachment ordering for the first prompt.
ui/goose2/src-tauri/src/services/acp/manager/session_ops/tests.rs
Adds backend regression coverage for mixed attachment ordering. This protects the ACP prompt construction path during future changes.
ui/goose2/src-tauri/tauri.conf.json
Re-enables native drag-and-drop delivery in the Tauri window config. This lets Finder drops reach the desktop app again.
ui/goose2/src/app/AppShell.tsx
Threads generalized chat attachments through app-level chat startup state. This allows new sessions launched from the shell to preserve pending attachments.
ui/goose2/src/app/ui/AppShellContent.tsx
Updates shell content props to pass attachment drafts into chat creation flows. This keeps the ported shell wiring consistent with the new attachment model.
ui/goose2/src/features/chat/hooks/ArtifactPolicyContext.tsx
Stops read-only file inspection tool calls from surfacing as artifact pills. This keeps the artifact UI focused on created outputs rather than inspected inputs.
ui/goose2/src/features/chat/hooks/tests/ArtifactPolicyContext.test.tsx
Adds regression tests proving read-only file and path inspection no longer create artifact pills. This protects the intended transcript behavior.
ui/goose2/src/features/chat/hooks/tests/useChat.attachments.test.ts
Splits attachment-specific send-path coverage into dedicated tests. These tests cover mixed attachments and attachment-aware prompt construction.
ui/goose2/src/features/chat/hooks/tests/useChat.test.ts
Keeps the base chat hook tests focused on the non-attachment flow. This reduces noise now that attachment behavior has its own test file.
ui/goose2/src/features/chat/hooks/tests/useMessageQueue.test.ts
Updates queue tests to cover attachment-aware draft persistence and replay. This ensures queued sends preserve attachment metadata correctly.
ui/goose2/src/features/chat/hooks/useAttachmentDropTarget.ts
Introduces a mixed attachment drop target for files, folders, and browser file drops. This replaces the earlier image-only drop handling.
ui/goose2/src/features/chat/hooks/useChat.ts
Generalizes send logic to accept attachment drafts, build attachment-aware prompts, and derive titles for attachment-only sessions. This is the core chat-layer support for the feature.
ui/goose2/src/features/chat/hooks/useChatInputAttachments.ts
Extracts attachment draft creation, normalization, preview handling, and dedupe into a dedicated hook. It also carries the platform-aware dedupe fix from the follow-up PR.
ui/goose2/src/features/chat/hooks/useImageDropTarget.ts
Removes the obsolete image-only drop hook. Mixed attachment handling now lives in the shared attachment drop target.
ui/goose2/src/features/chat/hooks/useMessageQueue.ts
Updates queued message handling so attachment metadata survives delayed sends. This keeps queued messages aligned with the new transcript model.
ui/goose2/src/features/chat/lib/artifactPathPolicy.ts
Exports the path policy helper used to distinguish read-only path access from created artifacts. This supports the updated artifact pill logic.
ui/goose2/src/features/chat/lib/attachments.ts
Adds helpers for attachment metadata, prompt preambles, and conversion between local attachments and message content. This centralizes the attachment formatting logic.
ui/goose2/src/features/chat/lib/sessionTitle.test.ts
Adds tests for deterministic titles when chats start with attachments only. This prevents blank or confusing sidebar labels.
ui/goose2/src/features/chat/lib/sessionTitle.ts
Introduces fallback attachment-only session titles like “Attached file”. This improves chat discoverability when no typed text is sent.
ui/goose2/src/features/chat/stores/chatStore.ts
Updates chat store typing to carry generalized attachments instead of image-only drafts. This aligns app state with the new attachment model.
ui/goose2/src/features/chat/ui/ChatInput.tsx
Refactors the composer to support shared attachment drafts, file and folder picker actions, drag-and-drop, and attachment-only sends. It also includes the follow-up fix to await async path loading inside the picker error boundary.
ui/goose2/src/features/chat/ui/ChatInputAttachments.tsx
Adds the composer attachment strip for image previews plus file and folder chips. This gives users a clear pre-send view of attached items.
ui/goose2/src/features/chat/ui/ChatInputToolbar.tsx
Adds the attach menu with separate file and folder entry points. This exposes the new attachment capabilities from the chat toolbar.
ui/goose2/src/features/chat/ui/ChatView.tsx
Passes generalized attachments through the chat view and session-creation wiring. This keeps the view layer aligned with the new draft shape.
ui/goose2/src/features/chat/ui/MessageBubble.tsx
Renders sent file and folder attachment chips in the transcript and lets users open their underlying paths. This makes sent attachments visible and actionable after send.
ui/goose2/src/features/chat/ui/tests/ChatInput.attachments.test.tsx
Adds dedicated composer tests for attach actions, mixed attachment rendering, drag overlays, and the follow-up dedupe behavior on case-insensitive platforms. This protects the main user-facing entry points.
ui/goose2/src/features/chat/ui/tests/MessageBubble.test.tsx
Adds transcript coverage for file and folder attachment chips. This verifies the post-send attachment rendering path.
ui/goose2/src/features/home/ui/HomeScreen.tsx
Updates the home screen chat launch flow to preserve generalized attachments into new sessions. This keeps attachment starts consistent across entry points.
ui/goose2/src/shared/api/system.ts
Adds frontend wrappers for attachment path inspection and local image loading commands. This is the frontend bridge into the new Tauri backend surface.
ui/goose2/src/shared/i18n/locales/en/chat.json
Adds English strings for attachment menus, drag-and-drop copy, open actions, and attachment-only titles. This completes the attachment UX copy.
ui/goose2/src/shared/i18n/locales/es/chat.json
Adds the Spanish translations for the new attachment UX. This keeps the feature localized alongside the rest of the chat surface.
ui/goose2/src/shared/types/messages.ts
Expands shared message types to describe image, file, and directory attachment drafts and metadata. This unifies attachment typing across the app.
Reproduction Steps
ui/goose2and start a new desktop chat.Screenshots/Demos
Validated locally in the Tauri desktop app after porting the old Goose 2 attachment work into this repo. No screenshots are attached to this PR.
Screen.Recording.2026-04-13.at.2.03.43.PM.mov