feat(app): add @ workspace file autocomplete in agent chat

This commit is contained in:
Mohamed Boudra
2026-02-18 13:25:55 +07:00
parent b1955cf74d
commit d30bb84741
16 changed files with 7993 additions and 7680 deletions
@@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest";
import { describe, expect, it } from 'vitest'
import {
AgentStreamMessageSchema,
@@ -6,172 +6,176 @@ import {
SessionInboundMessageSchema,
SessionOutboundMessageSchema,
WSOutboundMessageSchema,
} from "./messages.js";
} from './messages.js'
describe("shared messages stream parsing", () => {
it("parses representative fetch_agent_timeline_response payload", () => {
describe('shared messages stream parsing', () => {
it('parses representative fetch_agent_timeline_response payload', () => {
const parsed = FetchAgentTimelineResponseMessageSchema.parse({
type: "fetch_agent_timeline_response",
type: 'fetch_agent_timeline_response',
payload: {
requestId: "req-1",
agentId: "agent_live",
direction: "tail",
projection: "projected",
epoch: "epoch-1",
requestId: 'req-1',
agentId: 'agent_live',
direction: 'tail',
projection: 'projected',
epoch: 'epoch-1',
reset: false,
staleCursor: false,
gap: false,
window: { minSeq: 1, maxSeq: 2, nextSeq: 3 },
startCursor: { epoch: "epoch-1", seq: 1 },
endCursor: { epoch: "epoch-1", seq: 2 },
startCursor: { epoch: 'epoch-1', seq: 1 },
endCursor: { epoch: 'epoch-1', seq: 2 },
hasOlder: false,
hasNewer: false,
entries: [
{
provider: "codex",
item: { type: "assistant_message", text: "hello" },
timestamp: "2026-02-08T20:10:00.000Z",
provider: 'codex',
item: { type: 'assistant_message', text: 'hello' },
timestamp: '2026-02-08T20:10:00.000Z',
seqStart: 1,
seqEnd: 2,
sourceSeqRanges: [{ startSeq: 1, endSeq: 2 }],
collapsed: ["assistant_merge"],
collapsed: ['assistant_merge'],
},
],
error: null,
},
});
})
expect(parsed.payload.entries).toHaveLength(1);
expect(parsed.payload.entries[0]?.item.type).toBe("assistant_message");
});
expect(parsed.payload.entries).toHaveLength(1)
expect(parsed.payload.entries[0]?.item.type).toBe('assistant_message')
})
it("parses representative agent_stream tool_call event", () => {
it('parses representative agent_stream tool_call event', () => {
const parsed = AgentStreamMessageSchema.parse({
type: "agent_stream",
type: 'agent_stream',
payload: {
agentId: "agent_live",
timestamp: "2026-02-08T20:10:00.000Z",
agentId: 'agent_live',
timestamp: '2026-02-08T20:10:00.000Z',
event: {
type: "timeline",
provider: "claude",
type: 'timeline',
provider: 'claude',
item: {
type: "tool_call",
callId: "call_live",
name: "shell",
status: "running",
type: 'tool_call',
callId: 'call_live',
name: 'shell',
status: 'running',
detail: {
type: "shell",
command: "ls",
type: 'shell',
command: 'ls',
},
error: null,
},
},
},
});
})
expect(parsed.payload.event.type).toBe("timeline");
if (parsed.payload.event.type === "timeline") {
expect(parsed.payload.event.item.type).toBe("tool_call");
if (parsed.payload.event.item.type === "tool_call") {
expect(parsed.payload.event.item.status).toBe("running");
expect(parsed.payload.event.type).toBe('timeline')
if (parsed.payload.event.type === 'timeline') {
expect(parsed.payload.event.item.type).toBe('tool_call')
if (parsed.payload.event.item.type === 'tool_call') {
expect(parsed.payload.event.item.status).toBe('running')
}
}
});
})
it("rejects removed initialize_agent_request inbound payload", () => {
it('rejects removed initialize_agent_request inbound payload', () => {
const parsed = SessionInboundMessageSchema.safeParse({
type: "initialize_agent_request",
agentId: "agent-legacy",
requestId: "req-legacy-1",
});
expect(parsed.success).toBe(false);
});
type: 'initialize_agent_request',
agentId: 'agent-legacy',
requestId: 'req-legacy-1',
})
expect(parsed.success).toBe(false)
})
it("rejects removed initialize_agent_request outbound payload", () => {
it('rejects removed initialize_agent_request outbound payload', () => {
const parsed = SessionOutboundMessageSchema.safeParse({
type: "initialize_agent_request",
type: 'initialize_agent_request',
payload: {
requestId: "req-legacy-1",
agentId: "agent-legacy",
agentStatus: "running",
requestId: 'req-legacy-1',
agentId: 'agent-legacy',
agentStatus: 'running',
timelineSize: 12,
},
});
expect(parsed.success).toBe(false);
});
})
expect(parsed.success).toBe(false)
})
it("parses directory suggestions request and response payloads", () => {
it('parses directory suggestions request and response payloads', () => {
const requestParsed = SessionInboundMessageSchema.safeParse({
type: "directory_suggestions_request",
query: "proj",
type: 'directory_suggestions_request',
query: 'proj',
cwd: '/tmp/project',
includeFiles: true,
includeDirectories: true,
limit: 20,
requestId: "req-dir-1",
});
expect(requestParsed.success).toBe(true);
requestId: 'req-dir-1',
})
expect(requestParsed.success).toBe(true)
const responseParsed = SessionOutboundMessageSchema.safeParse({
type: "directory_suggestions_response",
type: 'directory_suggestions_response',
payload: {
directories: ["/Users/test/projects/paseo"],
directories: ['/Users/test/projects/paseo'],
entries: [{ path: '/Users/test/projects/paseo', kind: 'directory' }],
error: null,
requestId: "req-dir-1",
requestId: 'req-dir-1',
},
});
expect(responseParsed.success).toBe(true);
});
})
expect(responseParsed.success).toBe(true)
})
it("rejects websocket envelope for removed agent_stream_snapshot message type", () => {
it('rejects websocket envelope for removed agent_stream_snapshot message type', () => {
const fixture = {
type: "agent_stream_snapshot",
type: 'agent_stream_snapshot',
payload: {
agentId: "agent-legacy",
agentId: 'agent-legacy',
events: [],
},
};
}
const wrapped = WSOutboundMessageSchema.safeParse({
type: "session",
type: 'session',
message: fixture,
});
expect(wrapped.success).toBe(false);
});
})
expect(wrapped.success).toBe(false)
})
it("rejects removed legacy git diff request messages", () => {
it('rejects removed legacy git diff request messages', () => {
const gitDiffParsed = SessionInboundMessageSchema.safeParse({
type: "git_diff_request",
agentId: "agent-1",
requestId: "req-1",
});
expect(gitDiffParsed.success).toBe(false);
type: 'git_diff_request',
agentId: 'agent-1',
requestId: 'req-1',
})
expect(gitDiffParsed.success).toBe(false)
const highlightedParsed = SessionInboundMessageSchema.safeParse({
type: "highlighted_diff_request",
agentId: "agent-1",
requestId: "req-2",
});
expect(highlightedParsed.success).toBe(false);
});
type: 'highlighted_diff_request',
agentId: 'agent-1',
requestId: 'req-2',
})
expect(highlightedParsed.success).toBe(false)
})
it("rejects removed legacy git diff response messages", () => {
it('rejects removed legacy git diff response messages', () => {
const gitDiffParsed = SessionOutboundMessageSchema.safeParse({
type: "git_diff_response",
type: 'git_diff_response',
payload: {
agentId: "agent-1",
diff: "",
agentId: 'agent-1',
diff: '',
error: null,
requestId: "req-1",
requestId: 'req-1',
},
});
expect(gitDiffParsed.success).toBe(false);
})
expect(gitDiffParsed.success).toBe(false)
const highlightedParsed = SessionOutboundMessageSchema.safeParse({
type: "highlighted_diff_response",
type: 'highlighted_diff_response',
payload: {
agentId: "agent-1",
agentId: 'agent-1',
files: [],
error: null,
requestId: "req-2",
requestId: 'req-2',
},
});
expect(highlightedParsed.success).toBe(false);
});
});
})
expect(highlightedParsed.success).toBe(false)
})
})
File diff suppressed because it is too large Load Diff