chore(tickets): sync store local — #307 QA verte finale backend+frontend, merge develop e1dbe56 (branche fix/307-startup-ghost-states-reconciliation commit 57cf825), carnet v7 section Git; AppImage rebuild 14:21 déjà formalisée v0.46.0 (commit dédié 99b400a + tag annoté, artefact sha256 vérifié identique au contenu develop post-merge — pas de nouveau tag); tickets 299-307 + index/counter + #296 carnet/issue; attachments/ et scripts/ hors périmètre; aucun push
This commit is contained in:
189
.ideai/tickets/305/carnet.md
Normal file
189
.ideai/tickets/305/carnet.md
Normal file
@ -0,0 +1,189 @@
|
||||
---
|
||||
issueRef: "#305"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
|
||||
updatedAt: 1789024612856
|
||||
---
|
||||
# Carnet #305 - Tâches planifiées projet avec outil MCP et menu utilisateur
|
||||
|
||||
## Demande
|
||||
- Date: 2026-09-10.
|
||||
- Ajouter des tâches planifiées liées au projet, gérées par IdeA plutôt que par le cron Linux.
|
||||
- Les agents doivent disposer d'un tool MCP pour créer des tâches récurrentes/projet.
|
||||
- L'utilisateur doit disposer d'un menu par projet pour créer, supprimer et modifier ces tasks.
|
||||
- Motivation: un projet a grossi build après build; l'orchestrateur a créé un cron Linux pour nettoyer régulièrement le dossier. Objectif: permettre cette automatisation dans IdeA, scoped au projet et visible/gérable.
|
||||
- Après livraison et QA: rebuild AppImage demandé.
|
||||
|
||||
## Contraintes initiales
|
||||
- Les tâches sont liées au projet, pas au système global Linux.
|
||||
- L'utilisateur doit pouvoir voir/modifier/supprimer ce que les agents créent.
|
||||
- Le tool MCP doit éviter que les agents contournent IdeA avec `crontab` système.
|
||||
- Sécurité: commandes planifiées potentiellement destructrices; besoin de permissions/sandbox claires.
|
||||
- Réutiliser le modèle background tasks pour les exécutions si pertinent, mais distinguer tâche planifiée et exécution ponctuelle.
|
||||
|
||||
## Cadrage UX
|
||||
Surface:
|
||||
- Ajouter l'entrée `Tâches planifiées` dans le menu du projet.
|
||||
- Surface unique pour les tâches créées par l'utilisateur et celles demandées par un agent.
|
||||
- Ligne: état, nom, fréquence, prochaine exécution, résultat dernière exécution, origine (`Créée par vous` ou `Créée par {agent}`), menu `Modifier`, `Exécuter maintenant`, `Suspendre/Reprendre`, `Supprimer`.
|
||||
- États visibles: `À approuver`, `Active`, `Suspendue`, `En cours`, `Échec`, `Projet inaccessible`.
|
||||
- État vide: `Aucune tâche planifiée pour ce projet` puis `Créez une tâche pour automatiser une commande récurrente sans utiliser le cron du système.`
|
||||
|
||||
Création/édition:
|
||||
- Action principale: `Nouvelle tâche planifiée`.
|
||||
- Champs: `Nom`, `Commande`, `Dossier de travail` relatif au projet par défaut, `Planification` (presets `Toutes les heures`, `Chaque jour`, `Chaque semaine`, option `Personnalisée`), `Fuseau horaire`, `Limite de durée`, `Permissions et sandbox`, `Activée`.
|
||||
- Avant activation: récapitulatif commande exacte, dossier, fréquence, prochaine exécution, permissions accordées.
|
||||
- Modification de commande/périmètre/planification/permissions repasse par validation.
|
||||
- Tâche créée par agent: état `À approuver`, ne s'exécute jamais silencieusement. Fiche: `Demandée par {agent}`, date et motif, commande/fréquence proposées, permissions nécessaires, actions `Approuver et activer`, `Modifier avant d’activer`, `Refuser`.
|
||||
- Le tool MCP doit retourner cet état à l'agent, sans prétendre que la tâche est active.
|
||||
|
||||
Sécurité UX:
|
||||
- Périmètre projet et profil sandbox toujours visibles.
|
||||
- Accès hors projet, réseau ou commandes potentiellement destructrices signalés explicitement.
|
||||
- Alerte: `Cette tâche pourra modifier ou supprimer des fichiers automatiquement.`
|
||||
- Activation initiale d'une tâche demandée par agent exige confirmation utilisateur.
|
||||
- Toute augmentation de permissions remet la tâche en état `À approuver`.
|
||||
- `Exécuter maintenant` utilise exactement les permissions planifiées.
|
||||
- Suppression active: confirmation `Supprimer définitivement cette tâche planifiée ?`.
|
||||
- Si exécution en cours: choix séparés `Supprimer après l’exécution` et `Arrêter puis supprimer`; ne jamais interrompre implicitement.
|
||||
|
||||
Exécutions:
|
||||
- Fiche: dernière/prochaine exécution, déclenchement `Planifié` ou `Manuel`, début, durée, code sortie, statut, stdout/stderr, permissions réellement utilisées, lien vers la tâche de fond correspondante.
|
||||
- Succès silencieux.
|
||||
- Échec: indicateur dans menu projet + notification discrète `Voir les détails`, sans avalanche de notifications répétées.
|
||||
- IdeA doit indiquer que l'application doit fonctionner pour déclencher les tâches.
|
||||
- Occurrences manquées pendant arrêt: pas de rattrapage en rafale; seule la prochaine occurrence future est programmée.
|
||||
- Projet inaccessible: exécution `Ignorée — projet inaccessible`, sans lancer ailleurs.
|
||||
|
||||
## Cadrage Architect
|
||||
Décision:
|
||||
- Backend + frontend + docs.
|
||||
- `BackgroundTask` est réutilisé uniquement pour les runs.
|
||||
- Une tâche planifiée est un nouvel agrégat durable distinct: intention récurrente; chaque déclenchement crée une `BackgroundTask`.
|
||||
|
||||
Source de vérité:
|
||||
- `<app_data_dir>/scheduled-project-tasks/<projectId>.json`.
|
||||
- Ne pas utiliser `cron`, `systemd timer`, ni fichier auto-exécuté dans le repo.
|
||||
- Machine-local et IdeA-owned pour éviter qu'un clone embarque une tâche destructrice.
|
||||
|
||||
Modèle domaine cible:
|
||||
```ts
|
||||
ScheduledProjectTask {
|
||||
id: ScheduledTaskId
|
||||
projectId: ProjectId
|
||||
name: string
|
||||
description?: string
|
||||
enabled: boolean
|
||||
command: { command: string; args: string[]; cwd?: string }
|
||||
schedule: Interval | Daily | Weekly
|
||||
timezone: string
|
||||
nextRunAtMs: number | null
|
||||
lastRunAtMs?: number
|
||||
lastTaskId?: TaskId
|
||||
createdBy: Human | Agent { agentId }
|
||||
updatedBy: Human | Agent { agentId }
|
||||
createdAtMs: number
|
||||
updatedAtMs: number
|
||||
auditRevision: number
|
||||
}
|
||||
```
|
||||
|
||||
V1 schedule borné:
|
||||
- `interval { everyMinutes }`, minimum configurable, défaut min 5 ou 15 minutes.
|
||||
- `daily { time: "HH:mm" }`.
|
||||
- `weekly { days: [...], time: "HH:mm" }`.
|
||||
- Pas de cron expression libre en V1.
|
||||
|
||||
Séparation schedule/run:
|
||||
- `ScheduledProjectTask` = définition visible, éditable, activable/désactivable.
|
||||
- `ScheduledTaskRun` optionnel = historique léger (`scheduleId`, `taskId`, `plannedAtMs`, `startedAtMs`, `status`).
|
||||
- `BackgroundTask` = exécution concrète, sortie attachable, cancel/retry existants.
|
||||
- Préférence architect: champ additif `origin: Scheduled { scheduledTaskId, plannedAtMs } | Manual` sur les runs/background tasks, plutôt que mélanger la nature et la provenance.
|
||||
|
||||
Ports/use cases:
|
||||
- `ScheduledProjectTaskStore`: `list(projectId)`, `get(projectId, scheduleId)`, `save(task)`, `delete(projectId, scheduleId)`, `list_due(nowMs)`.
|
||||
- `ScheduledProjectTaskAuditStore` ou audit via event store existant.
|
||||
- `ProjectTaskScheduler`: `reconcile_project(projectId)`, `arm(scheduleId, nextRunAtMs)`, `cancel(scheduleId)`.
|
||||
- Use cases: `ListScheduledProjectTasks`, `CreateScheduledProjectTask`, `UpdateScheduledProjectTask`, `DeleteScheduledProjectTask`, `RunScheduledProjectTaskNow`, `ReconcileScheduledProjectTasks`, `FireScheduledProjectTask`.
|
||||
- `FireScheduledProjectTask`: calcule prochain run, persiste avant spawn, puis appelle `SpawnBackgroundCommand` avec `wakePolicy = RecordOnly` par défaut.
|
||||
|
||||
Scheduler/boot:
|
||||
- Réutiliser `TokioScheduler` one-shot comme mécanisme de réveil, jamais comme source de vérité.
|
||||
- Au boot: charger projets connus; pour chaque projet ouvert/restauré, `reconcile_project(projectId)`.
|
||||
- V1: ne pas lancer de tâches pour projets fermés.
|
||||
- Si `nextRunAtMs <= now`: politique `skipMissedAndScheduleNext`, pas de rafale.
|
||||
- Si une run était `Running` avant crash: laisser le reconcile `BackgroundTask` existant marquer failed/lost handle.
|
||||
|
||||
Sécurité:
|
||||
- `cwd` confiné au project root.
|
||||
- Pas d'`env` libre V1, ou seulement références à variables existantes; jamais de secrets persistés.
|
||||
- Commande/args visibles intégralement avant activation.
|
||||
- Audit create/update/delete/enable/disable/runNow: actor, projectId, scheduleId, diff résumé, timestamp.
|
||||
- Tools MCP création/modification/suppression = `WriteAction`, soumis aux permissions MCP natives.
|
||||
- #305 fournit l'alternative visible au cron système; limiter les permissions shell/sandbox reste nécessaire pour empêcher un agent large de lancer `crontab` directement.
|
||||
|
||||
MCP tools à ajouter:
|
||||
- `idea_scheduled_task_list` read-only
|
||||
- `idea_scheduled_task_read` read-only
|
||||
- `idea_scheduled_task_create` write-action
|
||||
- `idea_scheduled_task_update` write-action
|
||||
- `idea_scheduled_task_delete` write-action
|
||||
- `idea_scheduled_task_run_now` write-action
|
||||
- `idea_scheduled_task_set_enabled` write-action
|
||||
- Project scope vient du serveur MCP du projet courant; l'agent ne choisit pas un autre projectId.
|
||||
|
||||
DTO/API Tauri + HTTP:
|
||||
- `list_scheduled_project_tasks(projectId)`
|
||||
- `create_scheduled_project_task(request)`
|
||||
- `update_scheduled_project_task(request)`
|
||||
- `delete_scheduled_project_task(projectId, scheduledTaskId)`
|
||||
- `run_scheduled_project_task_now(projectId, scheduledTaskId)`
|
||||
- `set_scheduled_project_task_enabled(projectId, scheduledTaskId, enabled)`
|
||||
- DTO camelCase: `nextRunAtMs`, `lastRunAtMs`, `lastTaskId`, `createdBy`, `updatedBy`.
|
||||
|
||||
Frontend:
|
||||
- Nouvelle surface projet/menu `Tâches planifiées`.
|
||||
- `ScheduledTaskGateway` dans ports/adapters Tauri/HTTP/mock.
|
||||
- Panneau liste + create/edit/delete/enable/run-now.
|
||||
- Lien vers `BackgroundTask` du dernier run si `lastTaskId` existe.
|
||||
- Ne pas fusionner avec WorkState: WorkState montre les runs; panneau planifié montre les définitions.
|
||||
|
||||
Docs:
|
||||
- Mettre à jour la doc MCP/agent-facing pour `idea_scheduled_task_*`.
|
||||
- `sdk/IdeaSDK/docs/services.md` si exposé aux plugins, sinon préciser que ce n'est pas un service plugin V1.
|
||||
- `sdk/IdeaSDK/docs/manifest.md` seulement si contributions plugin touchent les schedules, déconseillé V1.
|
||||
- Mentionner explicitement: ne pas utiliser cron système pour une maintenance projet IdeA.
|
||||
|
||||
Fichiers probables:
|
||||
- Backend: `crates/domain/src/scheduled_task.rs`, `crates/domain/src/ports.rs`, `crates/application/src/scheduled_task/mod.rs`, `crates/application/src/background/mod.rs`, `crates/infrastructure/src/store/scheduled_task.rs`, `crates/infrastructure/src/scheduler/mod.rs`, `crates/backend/src/lib.rs`, `crates/app-tauri/src/commands.rs`, `crates/backend/src/dto.rs`, `crates/web-server/src/lib.rs`, `crates/infrastructure/src/orchestrator/mcp/tools.rs`.
|
||||
- Frontend: `frontend/src/features/scheduled-tasks/*`, `frontend/src/ports/index.ts`, `frontend/src/adapters/scheduledTask.ts`, `frontend/src/adapters/http/requestResponseGateways.ts`, `frontend/src/adapters/mock/index.ts`, `frontend/src/features/projects/ProjectsView.tsx`, `frontend/src/features/web/webSurfaceCatalog.ts`.
|
||||
|
||||
## Critères QA
|
||||
- Une tâche utilisateur et une tâche créée via MCP apparaissent dans la même liste.
|
||||
- L'auteur, commande, fréquence, prochaine exécution et permissions sont identifiables.
|
||||
- Tâche demandée par agent ne s'exécute pas avant approbation.
|
||||
- Approuver/refuser/modifier/suspendre/reprendre/supprimer produisent les états attendus.
|
||||
- Modification sensible redemande une approbation.
|
||||
- Tâche suspendue ne s'exécute pas.
|
||||
- Exécution manuelle et planifiée sont distinguables/auditables.
|
||||
- Logs, durée, code de sortie et erreurs consultables.
|
||||
- Projet inaccessible ne bloque pas IdeA et ne déplace jamais l'exécution ailleurs.
|
||||
- Aucun rattrapage multiple après arrêt prolongé.
|
||||
- Suppression pendant exécution ne l'interrompt pas sans choix explicite.
|
||||
- Succès silencieux; échecs visibles sans notifications répétitives.
|
||||
- Horaires respectent le fuseau configuré.
|
||||
- Créer via MCP puis vérifier UI; créer/modifier/supprimer via UI puis vérifier MCP list/read.
|
||||
- Échéance atteinte: `BackgroundTask` créée, visible WorkState, sortie attachable.
|
||||
- Redémarrage avant échéance: reconcile rearme.
|
||||
- Redémarrage après échéance manquée: pas de rafale, prochaine échéance recalculée, audit missed/skipped.
|
||||
- Projet fermé: aucune exécution silencieuse.
|
||||
- `cwd` hors projet rejeté.
|
||||
- Tool MCP write refusé sans permission native.
|
||||
- Delete/disable annule le timer armé.
|
||||
- Deux reconciles concurrents ne créent pas deux runs pour la même échéance.
|
||||
|
||||
## Blocage — 2026-09-10
|
||||
- Git a préparé `feature/305-scheduled-project-tasks-mcp`, mais a recommandé de finaliser #304 avant de démarrer #305.
|
||||
- #304 est implémenté et QA vert, mais non committé/mergé: trois délégations Git pour le commit/merge #304 ont expiré à 600s malgré relance/rattachement.
|
||||
- Le worktree courant porte encore les deux fichiers frontend #304 modifiés. Main ne doit pas démarrer #305 ni changer de branche tant que cette topologie n'est pas résolue, pour éviter de mélanger les changements.
|
||||
- Prochaine reprise: débloquer Git ou faire exécuter par l'agent Git le commit/merge #304, puis checkout/rebase/reset de `feature/305-scheduled-project-tasks-mcp` par Git et lancer DevBackend #305.
|
||||
17
.ideai/tickets/305/issue.md
Normal file
17
.ideai/tickets/305/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "6b6abd28-59c9-4f07-a19c-fb3770ef1415"
|
||||
number: 305
|
||||
title: "Tâches planifiées projet avec outil MCP et menu utilisateur"
|
||||
status: "inProgress"
|
||||
priority: "high"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
|
||||
createdAt: 1789021772418
|
||||
updatedAt: 1789024612856
|
||||
version: 4
|
||||
---
|
||||
Demande utilisateur du 2026-09-10 : ajouter à IdeA des tâches planifiées liées au projet, gérables par IdeA plutôt que par le cron Linux. Les agents doivent disposer d'un tool MCP pour créer des tâches récurrentes/projet. L'utilisateur doit avoir un menu par projet pour créer, supprimer et modifier ces tasks. Motivation : éviter qu'un orchestrateur crée un cron système Linux pour nettoyer régulièrement un dossier projet qui grossit build après build. Une fois livré et validé, rebuild l'AppImage.
|
||||
Reference in New Issue
Block a user