feat: add main features

Agents for developpement added + frontend add + backend added. Git viewer created + agent and template creator + layout and project creator
This commit is contained in:
2026-06-06 01:27:01 +02:00
parent 55b3bee2c8
commit 307ae71857
273 changed files with 48740 additions and 0 deletions

View File

@ -0,0 +1,108 @@
/**
* Tauri adapter for {@link AgentGateway} (L6).
*
* NOTE: The Tauri commands wired here (`list_agents`, `create_agent`, …) are
* defined in the backend `app-tauri` crate and will be registered in a
* subsequent lot. This adapter is complete on the frontend side; the mock
* gateway covers tests and offline dev today. The real mode will work
* transparently once the commands are registered.
*
* Commands use snake_case (Tauri convention); payload keys are camelCase
* (matching the backend DTO `#[serde(rename_all = "camelCase")]`), consistent
* with the other adapters in this directory.
*/
import { Channel, invoke } from "@tauri-apps/api/core";
import type { Agent } from "@/domain";
import type {
AgentGateway,
CreateAgentInput,
OpenTerminalOptions,
TerminalHandle,
} from "@/ports";
/** Wire shape returned by the `launch_agent` command (mirrors `open_terminal`). */
interface LaunchAgentResponse {
sessionId: string;
cwd: string;
rows: number;
cols: number;
}
export class TauriAgentGateway implements AgentGateway {
listAgents(projectId: string): Promise<Agent[]> {
return invoke<Agent[]>("list_agents", { projectId });
}
createAgent(projectId: string, input: CreateAgentInput): Promise<Agent> {
// The `create_agent` command takes a single `request` DTO; `projectId` must
// live *inside* it (camelCase), not at the top level.
return invoke<Agent>("create_agent", {
request: {
projectId,
name: input.name,
profileId: input.profileId,
initialContent: input.initialContent ?? null,
},
});
}
readContext(projectId: string, agentId: string): Promise<string> {
return invoke<string>("read_agent_context", { projectId, agentId });
}
async updateContext(
projectId: string,
agentId: string,
content: string,
): Promise<void> {
// `update_agent_context` takes a single `request` DTO.
await invoke("update_agent_context", {
request: { projectId, agentId, content },
});
}
async deleteAgent(projectId: string, agentId: string): Promise<void> {
await invoke("delete_agent", { projectId, agentId });
}
async launchAgent(
projectId: string,
agentId: string,
options: OpenTerminalOptions,
onData: (bytes: Uint8Array) => void,
): Promise<TerminalHandle> {
// Per-session output channel. The backend serialises chunks as byte arrays.
const channel = new Channel<number[]>();
channel.onmessage = (chunk) => onData(Uint8Array.from(chunk));
const res = await invoke<LaunchAgentResponse>("launch_agent", {
request: {
projectId,
agentId,
rows: options.rows,
cols: options.cols,
},
onOutput: channel,
});
const sessionId = res.sessionId;
return {
sessionId,
async write(data: Uint8Array): Promise<void> {
await invoke("write_terminal", {
request: { sessionId, data: Array.from(data) },
});
},
async resize(rows: number, cols: number): Promise<void> {
await invoke("resize_terminal", {
request: { sessionId, rows, cols },
});
},
async close(): Promise<void> {
await invoke("close_terminal", { sessionId });
},
};
}
}