Expose la surface produit des limites de session côté React/TS,
au-dessus du câblage backend (9df5923).
- domain/index.ts : 5 variantes ajoutées au union DomainEvent
(agentRateLimited / ResumeScheduled / ResumeCancelled / Resumed /
RateLimitSuspected).
- ports/index.ts : cancelResume(agentId) ajouté à InputGateway.
- adapters/input.ts : TauriInputGateway.cancelResume → invoke("cancel_resume").
- adapters/mock/index.ts : MockInputGateway.cancelResume
(cancelledResumes / cancelResumeResult).
- features/agents/useAgents.ts : état limitByAgent + action cancelResume.
- features/agents/AgentLimitBadge.tsx (nouveau) : badge + compte à rebours
+ bouton Annuler + helpers purs.
- features/agents/AgentsPanel.tsx : câblage du badge.
Tests : useAgentsLimits.test.tsx (13) + AgentLimitBadge.test.tsx (11),
suite agents 63 tests verts, tsc --noEmit propre.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
/**
|
|
* Tauri adapter for {@link InputGateway} (ARCHITECTURE §20.3).
|
|
*
|
|
* `interrupt` → `interrupt_agent` (preempt). `delegationDelivered` →
|
|
* `delegation_delivered` (the native write-portal's ack that a delegation's
|
|
* text was effectively written into the PTY). The former `submit` →
|
|
* `submit_agent_input` path is gone: the agent cell is a native terminal, so
|
|
* human keystrokes reach the PTY directly (no mediated-input strip).
|
|
*
|
|
* 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 { invoke } from "@tauri-apps/api/core";
|
|
|
|
import type { InputGateway } from "@/ports";
|
|
|
|
export class TauriInputGateway implements InputGateway {
|
|
async interrupt(projectId: string, agentId: string): Promise<void> {
|
|
await invoke("interrupt_agent", {
|
|
request: { projectId, agentId },
|
|
});
|
|
}
|
|
|
|
async delegationDelivered(
|
|
projectId: string,
|
|
agentId: string,
|
|
ticket: string,
|
|
): Promise<void> {
|
|
await invoke("delegation_delivered", {
|
|
request: { projectId, agentId, ticket },
|
|
});
|
|
}
|
|
|
|
async setFrontAttached(agentId: string, attached: boolean): Promise<void> {
|
|
await invoke("set_front_attached", {
|
|
request: { agentId, attached },
|
|
});
|
|
}
|
|
|
|
async cancelResume(agentId: string): Promise<boolean> {
|
|
// `cancel_resume` takes a bare `agent_id` (camelCase `agentId`), not a
|
|
// `request` envelope, and returns whether a pending resume was disarmed.
|
|
return invoke<boolean>("cancel_resume", { agentId });
|
|
}
|
|
}
|