feat(agent): menu de profils restreint Claude/Codex + retrait custom (D7) — §17
Dernier lot de §17 : seuls les profils pilotables en mode structuré sont proposés à la sélection/création. - domain : AgentProfile::is_selectable() = structured_adapter.is_some(), source unique de vérité du prédicat. - infrastructure : AgentSessionFactory::supports délègue à is_selectable (supports et is_selectable ne peuvent plus diverger). - application : selectable_reference_profiles() = reference_profiles() filtré ; ReferenceProfiles et FirstRunState exposent la liste filtrée (Claude/Codex). reference_profiles() brut reste à 4 (data intacte) ⇒ un agent Gemini/Aider/custom legacy déjà configuré continue de tourner. - frontend : bloc AddCustomProfile retiré du wizard first-run, action addCustom retirée du viewmodel ; wizard n'affiche que la liste filtrée. Tests (QA) : is_selectable (table de vérité), cohérence stricte is_selectable<->supports, liste exposée=2 / data brute=4, garde anti-régression Vitest sur l'absence du bloc custom — validées par mutation. cargo test --workspace : 820 passed. npx vitest run : 344 passed. §17 COMPLET (D0->D7). Suivi restant : D6b (surfacer reply dans le writer wire .response.json pour la délégation par protocole fichier). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -1160,7 +1160,13 @@ class MockRemoteGateway implements RemoteGateway {
|
||||
async connect(): Promise<void> {}
|
||||
}
|
||||
|
||||
/** The pre-filled reference catalogue the mock serves (mirror of the backend). */
|
||||
/**
|
||||
* The pre-filled reference catalogue the mock serves — mirror of the backend's
|
||||
* **selectable** catalogue (§17.3/D7): only profiles drivable in structured mode
|
||||
* (Claude + Codex) are offered to selection/creation. Gemini/Aider stay in the
|
||||
* backend's raw catalogue data but are filtered out of the selection path, so the
|
||||
* mock must not serve them either.
|
||||
*/
|
||||
export const MOCK_REFERENCE_PROFILES: AgentProfile[] = [
|
||||
{
|
||||
id: "mock-claude",
|
||||
@ -1180,24 +1186,6 @@ export const MOCK_REFERENCE_PROFILES: AgentProfile[] = [
|
||||
detect: "codex --version",
|
||||
cwdTemplate: "{projectRoot}",
|
||||
},
|
||||
{
|
||||
id: "mock-gemini",
|
||||
name: "Gemini CLI",
|
||||
command: "gemini",
|
||||
args: [],
|
||||
contextInjection: { strategy: "conventionFile", target: "GEMINI.md" },
|
||||
detect: "gemini --version",
|
||||
cwdTemplate: "{projectRoot}",
|
||||
},
|
||||
{
|
||||
id: "mock-aider",
|
||||
name: "Aider",
|
||||
command: "aider",
|
||||
args: [],
|
||||
contextInjection: { strategy: "flag", flag: "--message-file {path}" },
|
||||
detect: "aider --version",
|
||||
cwdTemplate: "{projectRoot}",
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@ -21,15 +21,15 @@ function customProfile(id: string, command: string): AgentProfile {
|
||||
}
|
||||
|
||||
describe("MockProfileGateway", () => {
|
||||
it("firstRunState is first-run with the four reference profiles", async () => {
|
||||
it("firstRunState is first-run with only the selectable reference profiles", async () => {
|
||||
// §17.3/D7: only structured-drivable profiles (Claude/Codex) are offered;
|
||||
// Gemini/Aider are filtered out of the selection path server-side.
|
||||
const gw = new MockProfileGateway();
|
||||
const state = await gw.firstRunState();
|
||||
expect(state.isFirstRun).toBe(true);
|
||||
expect(state.referenceProfiles.map((p) => p.command)).toEqual([
|
||||
"claude",
|
||||
"codex",
|
||||
"gemini",
|
||||
"aider",
|
||||
]);
|
||||
});
|
||||
|
||||
@ -51,8 +51,6 @@ describe("MockProfileGateway", () => {
|
||||
expect(byCommand).toEqual({
|
||||
claude: true,
|
||||
codex: false,
|
||||
gemini: false,
|
||||
aider: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user