From 9b1ced50beaf95e3491d200a290015e548253e7c Mon Sep 17 00:00:00 2001 From: Blomios Date: Thu, 30 Jul 2026 12:55:57 +0200 Subject: [PATCH 1/2] feat(ui): uniformise les droplist dynamiques sur le style du picker d'agent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduit SmallDropdown comme composant partagé et le fait adopter par AgentsPanel, ModelServerSelect, OpenCodeModeFields, TemplateEditor et TicketViewportSelect, pour que toutes les listes déroulantes dynamiques (agent, modèle, template, viewport) partagent la même apparence que le sélecteur d'agent de la création de ticket. Refs #114 Co-Authored-By: Claude Sonnet 5 --- frontend/src/features/agents/AgentsPanel.tsx | 120 +++---- frontend/src/features/agents/agents.test.tsx | 47 +-- .../first-run/FirstRunWizard.test.tsx | 30 +- .../features/first-run/OpenCodeModeFields.tsx | 77 ++--- .../first-run/ProfilesSettings.test.tsx | 16 +- .../model-servers/ModelServerSelect.tsx | 32 +- .../model-servers/modelServers.test.tsx | 16 +- frontend/src/features/skills/skills.test.tsx | 9 +- .../src/features/templates/TemplateEditor.tsx | 26 +- .../src/features/templates/templates.test.tsx | 14 +- .../features/tickets/TicketViewportSelect.tsx | 178 +---------- frontend/src/shared/index.ts | 3 + frontend/src/shared/ui/SmallDropdown.tsx | 296 ++++++++++++++++++ frontend/src/shared/ui/ui.test.tsx | 46 +++ 14 files changed, 550 insertions(+), 360 deletions(-) create mode 100644 frontend/src/shared/ui/SmallDropdown.tsx diff --git a/frontend/src/features/agents/AgentsPanel.tsx b/frontend/src/features/agents/AgentsPanel.tsx index c9c78d8..7a2b245 100644 --- a/frontend/src/features/agents/AgentsPanel.tsx +++ b/frontend/src/features/agents/AgentsPanel.tsx @@ -16,7 +16,7 @@ import { useEffect, useState } from "react"; -import { Button, Input, Panel, Spinner, cn } from "@/shared"; +import { Button, Input, Panel, SmallDropdown, Spinner, cn } from "@/shared"; import { TerminalView } from "@/features/terminals/TerminalView"; import { AnnouncementsPreview } from "@/features/announcements"; import { useDrift } from "@/features/templates/useDrift"; @@ -287,25 +287,19 @@ export function AgentsPanel({ projectId, projectRoot = "" }: AgentsPanelProps) { > Template - + size="md" + options={[ + { value: "", label: "(none / from scratch)" }, + ...templates.map((t) => ({ value: t.id, label: t.name })), + ]} + /> {/* Profile selector — hidden when a template is chosen */} @@ -321,24 +315,21 @@ export function AgentsPanel({ projectId, projectRoot = "" }: AgentsPanelProps) { )} {vm.profiles.length > 0 ? ( - + onChange={setNewProfileId} + className="w-full" + size="md" + options={[ + { value: "", label: "— select profile —" }, + ...vm.profiles.map((p) => ({ + value: p.id, + label: profileLabel(p), + })), + ]} + /> ) : ( 0 && ( - + options={[ + ...(vm.profiles.every((p) => p.id !== a.profileId) + ? [{ value: a.profileId, label: a.profileId }] + : []), + ...vm.profiles.map((p) => ({ + value: p.id, + label: profileLabel(p), + })), + ]} + /> )} {agentDrift && ( - {open && - position && - createPortal( -
- {options.map((option) => ( - - ))} -
, - document.body, - )} - + ); } diff --git a/frontend/src/shared/index.ts b/frontend/src/shared/index.ts index 3e95840..25e3788 100644 --- a/frontend/src/shared/index.ts +++ b/frontend/src/shared/index.ts @@ -43,3 +43,6 @@ export type { MenuBarProps, MenuBarMenu, MenuBarItem } from "./ui/MenuBar"; export { DockRegion } from "./ui/DockRegion"; export type { DockRegionProps, DockSide } from "./ui/DockRegion"; + +export { SmallDropdown } from "./ui/SmallDropdown"; +export type { SmallDropdownProps, SmallDropdownOption } from "./ui/SmallDropdown"; diff --git a/frontend/src/shared/ui/SmallDropdown.tsx b/frontend/src/shared/ui/SmallDropdown.tsx new file mode 100644 index 0000000..25a2943 --- /dev/null +++ b/frontend/src/shared/ui/SmallDropdown.tsx @@ -0,0 +1,296 @@ +import { + useCallback, + useEffect, + useId, + useLayoutEffect, + useRef, + useState, +} from "react"; +import { createPortal } from "react-dom"; + +import { cn } from "@/shared/lib/cn"; +import { zIndex } from "./zIndex"; + +export interface SmallDropdownOption { + value: string; + label: string; + disabled?: boolean; +} + +export interface SmallDropdownProps { + ariaLabel?: string; + "aria-label"?: string; + value: string; + options: SmallDropdownOption[]; + onChange: (value: string) => void; + id?: string; + className?: string; + disabled?: boolean; + size?: "sm" | "md"; + invalid?: boolean; +} + +interface PopupPosition { + top: number; + left: number; + width: number; + maxHeight: number; + placement: "top" | "bottom"; +} + +const VIEWPORT_MARGIN = 8; +const MIN_POPUP_HEIGHT = 96; +const MAX_POPUP_HEIGHT = 280; + +function firstEnabledIndex(options: SmallDropdownOption[]): number { + return options.findIndex((option) => !option.disabled); +} + +function nextEnabledIndex( + options: SmallDropdownOption[], + from: number, + direction: 1 | -1, +): number { + if (options.length === 0) return -1; + for (let offset = 1; offset <= options.length; offset += 1) { + const index = (from + offset * direction + options.length) % options.length; + if (!options[index]?.disabled) return index; + } + return -1; +} + +export function SmallDropdown({ + ariaLabel: ariaLabelProp, + "aria-label": ariaLabelAttribute, + value, + options, + onChange, + id, + className, + disabled = false, + size = "sm", + invalid = false, +}: SmallDropdownProps) { + const idBase = useId(); + const triggerRef = useRef(null); + const popupRef = useRef(null); + const [open, setOpen] = useState(false); + const [position, setPosition] = useState(null); + const selectedIndex = options.findIndex((option) => option.value === value); + const selected = selectedIndex >= 0 ? options[selectedIndex] : options[0]; + const [activeIndex, setActiveIndex] = useState( + selectedIndex >= 0 ? selectedIndex : firstEnabledIndex(options), + ); + const ariaLabel = ariaLabelAttribute ?? ariaLabelProp ?? "select option"; + + const updatePosition = useCallback(() => { + const trigger = triggerRef.current; + if (!trigger) return; + + const rect = trigger.getBoundingClientRect(); + const viewportWidth = window.innerWidth || document.documentElement.clientWidth; + const viewportHeight = window.innerHeight || document.documentElement.clientHeight; + const popupWidth = Math.max(rect.width, 160); + const spaceBelow = viewportHeight - rect.bottom - VIEWPORT_MARGIN; + const spaceAbove = rect.top - VIEWPORT_MARGIN; + const placement = + spaceBelow < MIN_POPUP_HEIGHT && spaceAbove > spaceBelow ? "top" : "bottom"; + const available = Math.max( + MIN_POPUP_HEIGHT, + placement === "top" ? spaceAbove : spaceBelow, + ); + const maxHeight = Math.min(MAX_POPUP_HEIGHT, available); + const left = Math.min( + Math.max(VIEWPORT_MARGIN, rect.left), + Math.max(VIEWPORT_MARGIN, viewportWidth - popupWidth - VIEWPORT_MARGIN), + ); + const top = + placement === "top" + ? Math.max(VIEWPORT_MARGIN, rect.top - maxHeight - 4) + : Math.min(viewportHeight - VIEWPORT_MARGIN, rect.bottom + 4); + + setPosition({ top, left, width: popupWidth, maxHeight, placement }); + }, []); + + const openPopup = useCallback(() => { + if (disabled) return; + const nextActive = selectedIndex >= 0 ? selectedIndex : firstEnabledIndex(options); + setActiveIndex(nextActive); + setOpen(true); + }, [disabled, options, selectedIndex]); + + const closePopup = useCallback(() => { + setOpen(false); + }, []); + + const selectOption = useCallback( + (option: SmallDropdownOption | undefined) => { + if (!option || option.disabled) return; + onChange(option.value); + closePopup(); + triggerRef.current?.focus(); + }, + [closePopup, onChange], + ); + + useLayoutEffect(() => { + if (!open) return; + updatePosition(); + }, [open, updatePosition]); + + useEffect(() => { + if (!open) return; + + function onPointerDown(event: PointerEvent) { + const target = event.target as Node | null; + if ( + target && + (triggerRef.current?.contains(target) || popupRef.current?.contains(target)) + ) { + return; + } + closePopup(); + } + + function onKeyDown(event: KeyboardEvent) { + if (event.key === "Escape") { + event.preventDefault(); + closePopup(); + triggerRef.current?.focus(); + return; + } + if (event.key === "ArrowDown" || event.key === "ArrowUp") { + event.preventDefault(); + setActiveIndex((current) => + nextEnabledIndex(options, current, event.key === "ArrowDown" ? 1 : -1), + ); + return; + } + if (event.key === "Home") { + event.preventDefault(); + setActiveIndex(firstEnabledIndex(options)); + return; + } + if (event.key === "End") { + event.preventDefault(); + setActiveIndex(nextEnabledIndex(options, 0, -1)); + return; + } + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + selectOption(options[activeIndex]); + } + } + + const onViewportChange = () => { + updatePosition(); + }; + + document.addEventListener("pointerdown", onPointerDown); + document.addEventListener("keydown", onKeyDown); + window.addEventListener("resize", onViewportChange); + window.addEventListener("scroll", onViewportChange, true); + window.visualViewport?.addEventListener("resize", onViewportChange); + window.visualViewport?.addEventListener("scroll", onViewportChange); + + return () => { + document.removeEventListener("pointerdown", onPointerDown); + document.removeEventListener("keydown", onKeyDown); + window.removeEventListener("resize", onViewportChange); + window.removeEventListener("scroll", onViewportChange, true); + window.visualViewport?.removeEventListener("resize", onViewportChange); + window.visualViewport?.removeEventListener("scroll", onViewportChange); + }; + }, [activeIndex, closePopup, open, options, selectOption, updatePosition]); + + const popupId = `${idBase}-listbox`; + const activeOptionId = + open && activeIndex >= 0 ? `${idBase}-option-${activeIndex}` : undefined; + + return ( + <> + + {open && + position && + createPortal( +
+ {options.map((option, index) => ( + + ))} +
, + document.body, + )} + + ); +} diff --git a/frontend/src/shared/ui/ui.test.tsx b/frontend/src/shared/ui/ui.test.tsx index bc1472b..03735fb 100644 --- a/frontend/src/shared/ui/ui.test.tsx +++ b/frontend/src/shared/ui/ui.test.tsx @@ -11,6 +11,7 @@ import { render, screen, fireEvent } from "@testing-library/react"; import { Button } from "./Button"; import { Input } from "./Input"; import { Field } from "./Field"; +import { SmallDropdown } from "./SmallDropdown"; import { Tabs } from "./Tabs"; describe("Button", () => { @@ -115,3 +116,48 @@ describe("Tabs", () => { expect(onClose).toHaveBeenCalledWith("b"); }); }); + +describe("SmallDropdown", () => { + const options = [ + { value: "", label: "None" }, + { value: "a", label: "Alpha" }, + { value: "b", label: "Beta", disabled: true }, + ]; + + it("opens a listbox and reports the selected value", () => { + const onChange = vi.fn(); + render( + , + ); + + fireEvent.click(screen.getByLabelText("test dropdown")); + fireEvent.click(screen.getByRole("option", { name: "Alpha" })); + + expect(onChange).toHaveBeenCalledWith("a"); + expect(screen.queryByRole("listbox")).toBeNull(); + }); + + it("supports keyboard selection and ignores disabled options", () => { + const onChange = vi.fn(); + render( + , + ); + + const trigger = screen.getByLabelText("test dropdown"); + fireEvent.keyDown(trigger, { key: "ArrowDown" }); + fireEvent.keyDown(document, { key: "ArrowDown" }); + fireEvent.keyDown(document, { key: "Enter" }); + + expect(onChange).toHaveBeenCalledWith("a"); + }); +}); From 5be5c5975e3251251393dc4d9461ab3e9c640e24 Mon Sep 17 00:00:00 2001 From: Blomios Date: Thu, 30 Jul 2026 12:56:07 +0200 Subject: [PATCH 2/2] =?UTF-8?q?chore(tickets):=20synchronise=20l'=C3=A9tat?= =?UTF-8?q?=20runtime=20des=20tickets=20et=20du=20contexte=20main?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Met à jour l'index/compteur de tickets, les tickets #111/#113/#114 et le contexte de Main suite au traitement du ticket #114. Co-Authored-By: Claude Sonnet 5 --- .ideai/agents/main.md | 13 ++++++ .ideai/mcp-tool-permissions.json | 7 ++-- .ideai/tickets/111/carnet.md | 69 ++++++++++++++++++++++++++++++-- .ideai/tickets/111/issue.md | 6 +-- .ideai/tickets/113/carnet.md | 6 +++ .ideai/tickets/113/issue.md | 17 ++++++++ .ideai/tickets/114/carnet.md | 6 +++ .ideai/tickets/114/issue.md | 17 ++++++++ .ideai/tickets/counter.json | 2 +- .ideai/tickets/index.json | 32 ++++++++++++++- 10 files changed, 164 insertions(+), 11 deletions(-) create mode 100644 .ideai/tickets/113/carnet.md create mode 100644 .ideai/tickets/113/issue.md create mode 100644 .ideai/tickets/114/carnet.md create mode 100644 .ideai/tickets/114/issue.md diff --git a/.ideai/agents/main.md b/.ideai/agents/main.md index 28607bb..0e33b53 100644 --- a/.ideai/agents/main.md +++ b/.ideai/agents/main.md @@ -109,3 +109,16 @@ Si la demande utilisateur contredit le cycle, rappelle brièvement la règle et --- *Dernière mise à jour : 2026-06-20* + +--- + +## Découverte exhaustive des outils MCP IdeA + +Codex charge les outils MCP de façon différée : une recherche sémantique peut ne retourner qu'un sous-ensemble des outils IdeA disponibles. Avant toute opération d'orchestration, de tickets, de mémoire, de contexte, de skills, de templates, de sprint, de workstate ou de tâche en arrière-plan : + +1. Inspecte le registre complet des outils disponibles et filtre le préfixe `mcp__idea__`. +2. Choisis l'outil natif IdeA le plus spécifique dans cet inventaire exhaustif. +3. N'utilise pas l'absence d'un outil dans les résultats partiels de recherche comme preuve de son indisponibilité. +4. Appelle les outils différés par leur nom exact via le registre lorsqu'ils ne sont pas exposés directement. + +Cette vérification de découverte est obligatoire au début de chaque workflow IdeA, afin que les outils natifs soient utilisés spontanément et pas seulement lorsqu'un utilisateur en rappelle le nom. \ No newline at end of file diff --git a/.ideai/mcp-tool-permissions.json b/.ideai/mcp-tool-permissions.json index 81552fd..9b3e50d 100644 --- a/.ideai/mcp-tool-permissions.json +++ b/.ideai/mcp-tool-permissions.json @@ -289,7 +289,7 @@ } }, { - "agentId": "a6ced819-b893-4213-b003-9e9dc79b9641", + "agentId": "dce19c75-9669-4e45-b8de-9950025157da", "policy": { "allowedTools": [ "idea_list_agents", @@ -326,7 +326,7 @@ } }, { - "agentId": "dce19c75-9669-4e45-b8de-9950025157da", + "agentId": "a6ced819-b893-4213-b003-9e9dc79b9641", "policy": { "allowedTools": [ "idea_list_agents", @@ -358,7 +358,8 @@ "idea_template_create", "idea_template_update", "idea_template_delete", - "idea_run_in_background" + "idea_run_in_background", + "idea_ask_agents" ] } } diff --git a/.ideai/tickets/111/carnet.md b/.ideai/tickets/111/carnet.md index 8a630b0..c0f6464 100644 --- a/.ideai/tickets/111/carnet.md +++ b/.ideai/tickets/111/carnet.md @@ -1,6 +1,69 @@ --- issueRef: "#111" -version: 2 -updatedBy: {"kind":"user"} -updatedAt: 1785331658707 +version: 3 +updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"} +updatedAt: 1785390694060 --- +## Enquete `/tmp` IdeA — inventaire et fenetres de cleanup + +### Methode +- Scan du code sur les usages `std::env::temp_dir()` / prexifes `idea-*` hors `frontend`. +- Lecture des blocs source pour separer `runtime` vs `#[cfg(test)]`. +- Verification du contenu live de `/tmp` au moment de l'analyse : aucun dossier `idea-*` visible a la racine de `/tmp` pendant ce tour. + +### Conclusion courte +- Les noms cites dans le ticket (`idea-structured-session-factory-*`, `idea-web-root-*`, `idea-server-test-*`, `idea-openai-compat-*`, etc.) ne correspondent pas, dans l'etat actuel du code, a des artefacts runtime produit. Ils proviennent majoritairement de tests embarques dans les crates Rust. +- Le seul artefact runtime clair lie a IdeA/MCP trouve pendant l'analyse est le repertoire parent `idea-mcp` qui heberge les sockets Unix par projet quand le runtime tombe sur `/tmp` comme base. +- Donc le modele `un call MCP -> un dossier temp -> suppression en fin de call` n'est pas le bon modele pour la majorite des cas observes. + +### Runtime reel identifie +#### 1. `idea-mcp` (runtime MCP par projet) +- Source : `crates/backend/src/mcp_endpoint.rs` et miroir `crates/app-tauri/src/mcp_endpoint.rs`. +- Role : repertoire parent des sockets Unix du serveur MCP local, ex. `/idea-mcp/.sock`. +- Creation : a la determination du endpoint MCP du projet si le sous-dossier `idea-mcp` n'existe pas deja. +- Granularite : par projet / par listener MCP, pas par appel d'outil MCP. +- Cleanup deja present : + - le fichier socket est unlink sur fermeture propre via `reclaim_name(true)` ; + - un socket cadavre est supprime avant rebind si c'est bien un socket stale ; + - refs utiles : `crates/backend/src/lib.rs` autour de `bind_endpoint()` et `crates/backend/src/mcp_endpoint.rs`. +- Cleanup opportun : + - **pas** a la fin de chaque call MCP ; + - **oui** a la fermeture du listener / fermeture du projet pour le fichier `.sock` ; + - **oui** au prochain demarrage / prochain bind pour nettoyer un socket stale d'un crash precedent ; + - **amelioration possible** : supprimer aussi le dossier parent `idea-mcp` s'il devient vide apres drop du dernier socket, ou faire un sweep best-effort au demarrage des endpoints MCP. +- Importance : c'est le seul candidat clairement runtime et potentiellement visible sous `/tmp` si `XDG_RUNTIME_DIR` / `TMPDIR` ne sont pas utilisables et que le fallback tombe sur `/tmp`. + +### Faux positifs / test-only observes +Ces prefixes existent dans le code mais dans des blocs de tests ou helpers de test. Ils ne semblent pas correspondre a des dossiers runtime utilisateur : +- `idea-openai-compat-*` : `crates/infrastructure/src/session/openai_compat.rs` +- `idea-structured-session-*` : `crates/infrastructure/src/session/mod.rs` +- `idea-web-root-*`, `idea-server-test-*`, `idea-server-lock-*`, `idea-app-data-env-*`, `idea-shared-core-*`, `idea-empty-web-*` : `crates/web-server/src/lib.rs` +- `idea-embedded-server-*` : `crates/app-tauri/src/embedded_server.rs` +- `idea-openai-mcp-tools-list-*`, `idea-openai-mcp-permissions-*`, variantes `app-tauri-*` : tests dans `crates/backend/src/openai_tools.rs` et `crates/app-tauri/src/openai_tools.rs` +- `idea-pty-sandbox-*`, `idea-landlock-*`, `idea-opencode-*`, `idea-devices-store-*`, `idea-secrets-store-*`, etc. : helpers de tests avec `Drop`/`remove_dir_all`. + +### Lecture sur leur cleanup +- Dans la majorite des cas de tests lus, le cleanup nominal existe deja (`Drop`, `remove_dir_all`, `remove_file`). +- Le vrai risque residuel de ces dossiers est surtout : crash/abort de test, kill brutal, ou interruption d'une suite de tests. Dans ce cas, le residue reste dans `/tmp`. +- Comme `/tmp` est borne a 16 Go, ces residues peuvent devenir un probleme d'hygiene, mais ce n'est pas un sujet de lifecycle MCP par call ; c'est plutot un sujet de hygiene de tests / sweep de reliquats. + +### Fenetres de cleanup recommandes +#### Runtime produit +- `idea-mcp/.sock` : cleanup a la fermeture du listener MCP (deja en place) ; stale cleanup avant bind (deja en place). +- `idea-mcp/` parent dir : cleanup best-effort si vide apres fermeture du dernier listener, ou sweep au demarrage de l'app / ouverture projet. + +#### Artefacts de tests +- Cleanup nominal dans chaque test/helper (souvent deja fait). +- Ajouter si besoin un sweep best-effort des prefixes `idea-*` generes par les tests au debut/fin des jobs de test locaux/CI. +- Ne pas melanger cela avec la logique runtime MCP : c'est un chantier distinct. + +### Recommandation de perimetre pour le ticket #111 +1. Cadrer `#111` sur les **artefacts runtime** visibles par l'utilisateur. +2. Traiter en priorite `idea-mcp` : + - verifier si le dossier parent vide reste parfois en place ; + - si oui, le supprimer quand il devient vide ou au prochain demarrage. +3. Ouvrir si necessaire un second ticket dedie a l'hygiene des reliquats de tests sous `/tmp`. + +### Reponse a la question produit initiale +- Oui, IdeA peut produire un artefact sous `/tmp` pour le MCP runtime (`idea-mcp`), mais ce n'est pas cree par appel MCP individuel. +- Non, les dossiers cites dans la description ne semblent pas, a ce stade, etre crees par les appels MCP IdeA de production ; ils sont majoritairement issus de tests. diff --git a/.ideai/tickets/111/issue.md b/.ideai/tickets/111/issue.md index 465470e..c3a991a 100644 --- a/.ideai/tickets/111/issue.md +++ b/.ideai/tickets/111/issue.md @@ -9,9 +9,9 @@ links: [] agentRefs: [] attachments: [] createdBy: {"kind":"user"} -updatedBy: {"kind":"user"} +updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"} createdAt: 1785331481527 -updatedAt: 1785331658707 -version: 2 +updatedAt: 1785390694060 +version: 3 --- dans le dossier /tmp, je vois enormement de dossier du genre : idea-structured-session-factory-openai-e5bbdcac-0405-4ce3-be82-00d9639ee648 ou encore idea-web-root-4fbc4144-065c-4915-9e05-9f6fec20aa3b ou idea-server-test-863efbe5-5098-4f34-aab8-1ba5047f4209 ou idea-openai-compat-unreachable-f713f5fa-5469-4875-96f9-242f7913441b ou idea-openai-compat-tools-rejected-d000d319-8c11-4585-8a16-6ae8a3b45c49 ou idea-openai-compat-status-422-9fd4b27f-e0c1-4043-9fb9-72dcf8d2c2e1 ou idea-openai-compat-single-final-940b1d63-6d4a-40b0-953a-0f3279ec2bdc etc qui sont visiblement créé par IdeA. J'aiemrais que pour un maximum d'entre eux, on puisse clean ça au bon momment. Il faut donc identifier ce qui créé ce cache, puis le supprimer quand ce cache n'est plus utile. \ No newline at end of file diff --git a/.ideai/tickets/113/carnet.md b/.ideai/tickets/113/carnet.md new file mode 100644 index 0000000..0d7d296 --- /dev/null +++ b/.ideai/tickets/113/carnet.md @@ -0,0 +1,6 @@ +--- +issueRef: "#113" +version: 4 +updatedBy: {"kind":"user"} +updatedAt: 1785395935541 +--- diff --git a/.ideai/tickets/113/issue.md b/.ideai/tickets/113/issue.md new file mode 100644 index 0000000..1f5675a --- /dev/null +++ b/.ideai/tickets/113/issue.md @@ -0,0 +1,17 @@ +--- +id: "1c128e50-96bd-4689-a080-f6b5e0c5a6b6" +number: 113 +title: "[Bug] Les espaces ne epuvent pas etre entrés dans les args du serveur llamacpp" +status: "open" +priority: "medium" +sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2" +links: [] +agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}] +attachments: [] +createdBy: {"kind":"user"} +updatedBy: {"kind":"user"} +createdAt: 1785395710201 +updatedAt: 1785395935541 +version: 4 +--- +Dnas les option de reglage llama.cpp de l'edition des serveurs locaux de modele llm, je ne peux pas entrer d'espaces dans le champs de texte Arguments supplémentaires. Il faut faire en sorte que ça soit possible \ No newline at end of file diff --git a/.ideai/tickets/114/carnet.md b/.ideai/tickets/114/carnet.md new file mode 100644 index 0000000..80a841b --- /dev/null +++ b/.ideai/tickets/114/carnet.md @@ -0,0 +1,6 @@ +--- +issueRef: "#114" +version: 4 +updatedBy: {"kind":"user"} +updatedAt: 1785395923498 +--- diff --git a/.ideai/tickets/114/issue.md b/.ideai/tickets/114/issue.md new file mode 100644 index 0000000..48bfd81 --- /dev/null +++ b/.ideai/tickets/114/issue.md @@ -0,0 +1,17 @@ +--- +id: "a7602792-21c6-40f3-852a-5200d604db9d" +number: 114 +title: "[UI] un iformiser les droplist" +status: "open" +priority: "medium" +sprint: "5afd6780-0f76-40d7-a10f-32ee52469d74" +links: [] +agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}] +attachments: [] +createdBy: {"kind":"user"} +updatedBy: {"kind":"user"} +createdAt: 1785395791597 +updatedAt: 1785395923498 +version: 4 +--- +Dans les différentes fenetres j'aimerais qu'on uniformise les droplist. C'est a dire que par exemple dans la fenetre de création de ticket, on a une droplist noire pour la selection d'un agent à lier, j'aimerais que ça soit la même droplist pour la selection du modele dans la fenetre des agents, dans la selection du template a la création d'un agent etc. Que toutes ces petites droplist dynamiques soient comme celle de selection de l'agent dans la fenetre de creation de tickets \ No newline at end of file diff --git a/.ideai/tickets/counter.json b/.ideai/tickets/counter.json index a5ca793..1961c89 100644 --- a/.ideai/tickets/counter.json +++ b/.ideai/tickets/counter.json @@ -1,3 +1,3 @@ { - "nextNumber": 113 + "nextNumber": 115 } \ No newline at end of file diff --git a/.ideai/tickets/index.json b/.ideai/tickets/index.json index d72e1d6..9cb3057 100644 --- a/.ideai/tickets/index.json +++ b/.ideai/tickets/index.json @@ -1461,7 +1461,7 @@ "createdBy": { "kind": "user" }, - "updatedAt": 1785331658707 + "updatedAt": 1785390694060 }, { "issueRef": "#112", @@ -1477,6 +1477,36 @@ "kind": "user" }, "updatedAt": 1785341341049 + }, + { + "issueRef": "#113", + "path": "113", + "title": "[Bug] Les espaces ne epuvent pas etre entrés dans les args du serveur llamacpp", + "status": "open", + "priority": "medium", + "sprint": "e28a4d53-8bd2-446a-b0ac-2a017373b8b2", + "assignedAgentIds": [ + "a6ced819-b893-4213-b003-9e9dc79b9641" + ], + "createdBy": { + "kind": "user" + }, + "updatedAt": 1785395935541 + }, + { + "issueRef": "#114", + "path": "114", + "title": "[UI] un iformiser les droplist", + "status": "open", + "priority": "medium", + "sprint": "5afd6780-0f76-40d7-a10f-32ee52469d74", + "assignedAgentIds": [ + "a6ced819-b893-4213-b003-9e9dc79b9641" + ], + "createdBy": { + "kind": "user" + }, + "updatedAt": 1785395923498 } ] } \ No newline at end of file