feat(workstate): UI live-state des conversations/délégations (Lot A frontend)
Ajoute le port et l'adaptateur workState (+ mock) côté frontend, le type domaine associé, et la feature `workstate` (panneau ProjectWorkStatePanel + hook useProjectWorkState) consommant le read-model live exposé par le backend. Intègre le panneau dans ProjectsView. Tests verts (workstate + projects). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -25,6 +25,7 @@ import { TauriMemoryGateway } from "./memory";
|
||||
import { TauriEmbedderGateway } from "./embedder";
|
||||
import { TauriGitGateway } from "./git";
|
||||
import { TauriPermissionGateway } from "./permission";
|
||||
import { TauriWorkStateGateway } from "./workState";
|
||||
|
||||
function notImplemented(what: string): never {
|
||||
const err: GatewayError = {
|
||||
@ -57,6 +58,7 @@ export function createTauriGateways(): Gateways {
|
||||
memory: new TauriMemoryGateway(),
|
||||
embedder: new TauriEmbedderGateway(),
|
||||
permission: new TauriPermissionGateway(),
|
||||
workState: new TauriWorkStateGateway(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -74,4 +76,5 @@ export {
|
||||
TauriEmbedderGateway,
|
||||
TauriGitGateway,
|
||||
TauriPermissionGateway,
|
||||
TauriWorkStateGateway,
|
||||
};
|
||||
|
||||
@ -31,6 +31,7 @@ import type {
|
||||
PermissionSet,
|
||||
Project,
|
||||
ProjectPermissions,
|
||||
ProjectWorkState,
|
||||
ProfileAvailability,
|
||||
ResumableAgent,
|
||||
Skill,
|
||||
@ -64,6 +65,7 @@ import type {
|
||||
TemplateGateway,
|
||||
TerminalGateway,
|
||||
TerminalHandle,
|
||||
WorkStateGateway,
|
||||
} from "@/ports";
|
||||
import { applyOperation, singleLeafTree } from "@/features/layout/layout";
|
||||
|
||||
@ -1648,6 +1650,19 @@ export class MockPermissionGateway implements PermissionGateway {
|
||||
}
|
||||
}
|
||||
|
||||
export class MockWorkStateGateway implements WorkStateGateway {
|
||||
private states = new Map<string, ProjectWorkState>();
|
||||
|
||||
/** Seeds the read-model returned for a project (deterministic tests/dev). */
|
||||
_setProjectWorkState(projectId: string, state: ProjectWorkState): void {
|
||||
this.states.set(projectId, structuredClone(state));
|
||||
}
|
||||
|
||||
async getProjectWorkState(projectId: string): Promise<ProjectWorkState> {
|
||||
return structuredClone(this.states.get(projectId) ?? { agents: [] });
|
||||
}
|
||||
}
|
||||
|
||||
function mostRestrictive(
|
||||
project?: PermissionSet["fallback"],
|
||||
agent?: PermissionSet["fallback"],
|
||||
@ -1676,6 +1691,7 @@ export function createMockGateways(): Gateways {
|
||||
memory: new MockMemoryGateway(),
|
||||
embedder: new MockEmbedderGateway(),
|
||||
permission: new MockPermissionGateway(),
|
||||
workState: new MockWorkStateGateway(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
17
frontend/src/adapters/workState.ts
Normal file
17
frontend/src/adapters/workState.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Tauri adapter for {@link WorkStateGateway}.
|
||||
*
|
||||
* This is the only frontend place that knows the `get_project_work_state`
|
||||
* command name; features consume the gateway port through DI.
|
||||
*/
|
||||
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
import type { ProjectWorkState } from "@/domain";
|
||||
import type { WorkStateGateway } from "@/ports";
|
||||
|
||||
export class TauriWorkStateGateway implements WorkStateGateway {
|
||||
getProjectWorkState(projectId: string): Promise<ProjectWorkState> {
|
||||
return invoke<ProjectWorkState>("get_project_work_state", { projectId });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user