feat: add workspace files to chat from Files and Changes

* feat(app): open changed files from context menu

* fix(app): preserve changed-file row behavior

* feat(app): add changed files to open chats

* feat(app): share file actions across explorer and changes

* feat(app): attach workspace files to focused chat

* feat(app): drag workspace files into chat

* refactor(app): use file actions menu for changed files

* fix(app): open changed-file actions on right click

* test(app): cover direct file attachment flow

* fix(app): enable add to chat on native

* fix(app): align workspace file pane rows

* refactor(app): simplify workspace file attachments

* fix(app): preserve uploaded file draft attachments

---------

Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
This commit is contained in:
nikuscs
2026-07-22 15:58:24 +02:00
committed by GitHub
co-authored by Mohamed Boudra
parent 42ee5a5949
commit bd937850b3
42 changed files with 1665 additions and 342 deletions
@@ -1,5 +1,9 @@
import { describe, expect, it } from "vitest";
import { applyFileMentionReplacement, findActiveFileMention } from "./file-mention-autocomplete";
import {
applyFileMentionReplacement,
findActiveFileMention,
formatQuotedFileMentionPath,
} from "./file-mention-autocomplete";
describe("findActiveFileMention", () => {
it("detects mentions at the start of input", () => {
@@ -46,6 +50,14 @@ describe("findActiveFileMention", () => {
});
});
describe("formatQuotedFileMentionPath", () => {
it("quotes workspace-relative paths using file mention escaping", () => {
expect(formatQuotedFileMentionPath('src/changed "file".ts')).toBe(
'"src/changed \\"file\\".ts"',
);
});
});
describe("applyFileMentionReplacement", () => {
it("replaces only the active @query segment with a quoted relative path", () => {
const text = "open @src/com next";
@@ -40,9 +40,13 @@ export function findActiveFileMention(input: FindActiveFileMentionInput): FileMe
return null;
}
export function formatQuotedFileMentionPath(relativePath: string): string {
const safePath = relativePath.replace(/"/g, '\\"');
return `"${safePath}"`;
}
export function applyFileMentionReplacement(input: ApplyFileMentionReplacementInput): string {
const safePath = input.relativePath.replace(/"/g, '\\"');
const before = input.text.slice(0, input.mention.start);
const after = input.text.slice(input.mention.end);
return `${before}"${safePath}"${after}`;
return `${before}${formatQuotedFileMentionPath(input.relativePath)}${after}`;
}