chore: consolidate ia_dev module, sync tooling, and harden gateways (0.0.5)

Initial state:
- ia_dev was historically referenced as ./ia_dev in docs and integrations, while the vendored module lives under services/ia_dev.
- AnythingLLM sync and hook installation had error masking / weak exit signaling.
- Proxy layers did not validate proxy path segments, allowing path normalization tricks.

Motivation:
- Make the IDE-oriented workflow usable (sync -> act -> deploy/preview) with explicit errors.
- Reduce security footguns in proxying and script automation.

Resolution:
- Standardize IA_DEV_ROOT usage and documentation to services/ia_dev.
- Add SSH remote data mirroring + optional AnythingLLM ingestion.
- Extend AnythingLLM pull sync to support upload-all/prefix and fail on upload errors.
- Harden smart-ide-sso-gateway and smart-ide-global-api proxying with safe-path checks and non-leaking error responses.
- Improve ia-dev-gateway runner validation and reduce sensitive path leakage.
- Add site scaffold tool (Vite/React) with OIDC + chat via sso-gateway -> orchestrator.

Root cause:
- Historical layout changes (submodule -> vendored tree) and missing central contracts for path resolution.
- Missing validation for proxy path traversal patterns.
- Overuse of silent fallbacks (|| true, exit 0 on partial failures) in automation scripts.

Impacted features:
- Project sync: git pull + AnythingLLM sync + remote data mirror ingestion.
- Site frontends: SSO gateway proxy and orchestrator intents (rag.query, chat.local).
- Agent execution: ia-dev-gateway script runner and SSE output.

Code modified:
- scripts/remote-data-ssh-sync.sh
- scripts/anythingllm-pull-sync/sync.mjs
- scripts/install-anythingllm-post-merge-hook.sh
- cron/git-pull-project-clones.sh
- services/smart-ide-sso-gateway/src/server.ts
- services/smart-ide-global-api/src/server.ts
- services/smart-ide-orchestrator/src/server.ts
- services/ia-dev-gateway/src/server.ts
- services/ia_dev/tools/site-generate.sh

Documentation modified:
- docs/** (architecture, API docs, ia_dev module + integration, scripts)

Configurations modified:
- config/services.local.env.example
- services/*/.env.example

Files in deploy modified:
- services/ia_dev/deploy/*

Files in logs impacted:
- logs/ia_dev.log (runtime only)
- .logs/* (runtime only)

Databases and other sources modified:
- None

Off-project modifications:
- None

Files in .smartIde modified:
- .smartIde/agents/*.md
- services/ia_dev/.smartIde/**

Files in .secrets modified:
- None

New patch version in VERSION:
- 0.0.5

CHANGELOG.md updated:
- yes
This commit is contained in:
Nicolas Cantu 2026-04-04 18:36:43 +02:00
parent 940cf59178
commit 58cc2493e5
190 changed files with 11517 additions and 273 deletions

5
.gitignore vendored
View File

@ -18,6 +18,9 @@ logs/**/*.log
# .logs/ : journaux SSO / API globale (README + .gitignore versionnés)
.logs/**/*.log
# Local mirrors of deployed data (SSH pull, RAG ingestion)
.data/
# projects/ : ignorer tout répertoire d'id sous projects/ sauf les squelettes versionnés (conf.json par id, gabarit example/)
projects/*
!projects/README.md
@ -37,3 +40,5 @@ builazoo/*
# Projet IDE actif (copie locale de active-project.json.example)
projects/active-project.json
.workspace
*.code-workspace

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/agent-loop.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/agent-loop.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/branch-align-by-script-from-test.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/branch-align-by-script-from-test.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/change-to-all-branches.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/change-to-all-branches.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/closure-point-7-justification.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/closure-point-7-justification.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/code.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/code.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/deploy-by-script.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/deploy-by-script.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/deploy-pprod-or-prod.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/deploy-pprod-or-prod.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/docupdate.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/docupdate.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/evol.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/evol.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/fix-lint.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/fix-lint.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/fix-search.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/fix-search.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/fix.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/fix.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/git-issues-process.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/git-issues-process.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/notary-ai-loop.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/notary-ai-loop.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/notary-ai-process.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/notary-ai-process.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,17 +7,17 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/push-by-script.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/push-by-script.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -7,19 +7,19 @@ is_background: false
## Contexte obligatoire (dépôt smart_ide → ia_dev)
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `ia_dev/projects/smart_ide`).
- **Identifiant projet ia_dev :** `smart_ide` (conf : `projects/smart_ide/` à la racine ; lien sous `services/ia_dev/projects/smart_ide`).
- **Environnement cible :** `test`, `pprod` ou `prod`. Le reprendre dans le message utilisateur ; **si absent, le demander** avant d'exécuter des scripts dépendants du env.
- **Racine des scripts ia_dev :** le dossier `ia_dev/` à la racine du workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Racine des scripts ia_dev :** le dossier `services/ia_dev/` dans le workspace **smart_ide**. Pour `deploy/`, `git-issues/`, etc. : se placer dans ce répertoire avant d'exécuter.
- **Variables / arguments :** `IA_PROJECT_ID=smart_ide` et/ou `--project smart_ide` selon le script ; référence : `docs/repo/ia-dev-project-conf-schema.md`.
- **MAIL_TO (ticketing / mails) :** exporter `MAIL_TO` avec l'adresse pour l'environnement choisi, lue dans `projects/smart_ide/conf.json` (racine workspace) → `tickets.authorized_emails.to` : test → `AI.SMART_IDE.TEST@4nkweb.com`, pprod → `AI.SMART_IDE.PPROD@4nkweb.com`, prod → `AI.SMART_IDE.PROD@4nkweb.com`.
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `ia_dev/` et chemins issus de `conf.json`).
- **Dépôt applicatif :** racine du workspace smart_ide ; `project_path` dans `conf.json` doit y pointer. Doc principale du monorepo : `docs/` à la racine (`projects/smart_ide/docs` sous services/ia_dev souvent absent).
- **Chemins machines** dans les agents ia_dev (autre machine utilisateur) : les remplacer par le clone réel (workspace + `services/ia_dev/` et chemins issus de `conf.json`).
- **`projects/*/conf.json` :** ne pas modifier sans validation utilisateur (règle ia_dev).
- **Périmètre hôte :** scripts et doc smart_ide pour le socle (Ollama, AnythingLLM, systemd, `setup/`, `scripts/`) ; les commandes définies dans l'agent ia_dev s'exécutent depuis `ia_dev/` lorsque la procédure l'exige.
- **Périmètre hôte :** scripts et doc smart_ide pour le socle (Ollama, AnythingLLM, systemd, `setup/`, `scripts/`) ; les commandes définies dans l'agent ia_dev s'exécutent depuis `services/ia_dev/` lorsque la procédure l'exige.
## Délégation
Lire le fichier **`ia_dev/.smartIde/agents/setup-host.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
Lire le fichier **`services/ia_dev/.smartIde/agents/setup-host.md`** et appliquer **intégralement** sa procédure et ses contraintes, en respectant le contexte ci-dessus.
**Référence résolution projet / env :** `docs/repo/ia-dev-project-conf-schema.md`.

View File

@ -1,3 +1,4 @@
{
"smartIde.activeProjectId": "smart_ide"
}

21
CHANGELOG.md Normal file
View File

@ -0,0 +1,21 @@
# Changelog
## 0.0.5 - 2026-04-04
### Added
- `scripts/remote-data-ssh-sync.sh`: mirror deployed data over SSH into `.data/remote-data/` and optionally ingest into AnythingLLM.
- AnythingLLM sync enhancements: `--upload-all` + `--upload-prefix` modes for non-git directory ingestion.
- `site-generate` ia_dev tool + gateway runner to scaffold Vite/React sites with OIDC + Smart IDE chat (via sso-gateway → orchestrator).
- Documentation: remote data SSH sync, E2E browser (Carbonyl manual mode).
### Changed
- Canonical `ia_dev` module location: `services/ia_dev/` (with `IA_DEV_ROOT` resolution); docs and integration updated accordingly.
- SSO gateway: upstream allowlist support via `SSO_ALLOWED_UPSTREAMS`.
- Global API: explicit `503` when an upstream requires a token but the token is not configured.
- `install-anythingllm-post-merge-hook.sh`: supports `--all` and `--project <id>` based on `projects/<id>/conf.json`.
### Fixed
- `cron/git-pull-project-clones.sh`: error propagation and summary exit code for failed pulls.

View File

@ -1 +1 @@
0.0.3
0.0.5

View File

@ -1,3 +1,6 @@
# builazoo
Racine du dépôt applicatif **builazoo** (clone Git ici). Configuration **smart_ide** / **ia_dev** : [`../projects/builazoo/conf.json`](../projects/builazoo/conf.json).
This directory is intentionally empty.
The application repository is expected as a sibling checkout (default: `../builazoo`), configured via `projects/builazoo/conf.json`.

View File

@ -18,6 +18,7 @@ GLOBAL_API_URL=http://127.0.0.1:37149
# OIDC_JWKS_URI=
# SSO_CORS_ORIGIN=
# SSO_GATEWAY_MAX_BODY_BYTES=33554432
# SSO_ALLOWED_UPSTREAMS=orchestrator
# --- Jetons / hôtes micro-services (consommés par smart-ide-global-api) ---
ORCHESTRATOR_HOST=127.0.0.1

View File

@ -20,6 +20,8 @@ elif [[ -n "${1:-}" && "$1" != "--all" ]]; then
usage
fi
err_count=0
command -v jq >/dev/null 2>&1 || {
echo "$LOG_PREFIX jq not found; install jq." >&2
exit 1
@ -77,6 +79,10 @@ for conf in "$PROJECTS_CONF"/*/conf.json; do
if [[ -n "$filter_id" && "$id" != "$filter_id" ]]; then
continue
fi
if [[ "$id" == "example" ]]; then
echo "$LOG_PREFIX skip $id: template project"
continue
fi
if [[ "$(jq -r '.cron.git_pull // true' "$conf")" == "false" ]]; then
echo "$LOG_PREFIX skip $id: cron.git_pull is false"
continue
@ -89,5 +95,12 @@ for conf in "$PROJECTS_CONF"/*/conf.json; do
if [[ "$path" != /* ]]; then
path="$(cd "$ROOT" && realpath -m "$path" 2>/dev/null || echo "$ROOT/$path")"
fi
pull_clone "$id" "$path" || true
if ! pull_clone "$id" "$path"; then
err_count=$((err_count + 1))
fi
done
if [[ "$err_count" -gt 0 ]]; then
echo "$LOG_PREFIX errors: $err_count (see output above)" >&2
exit 1
fi

View File

@ -23,14 +23,14 @@ Réponse `200` : `{ "status": "ok", "service": "smart-ide-global-api" }`.
### `GET /v1/upstreams`
Liste les clés damont : `{ "upstreams": [ "orchestrator", ... ] }` (même liste que côté SSO).
Liste les clés damont connues : `{ "upstreams": [ "orchestrator", ... ] }`. La passerelle SSO peut renvoyer un sous-ensemble (allowlist via `SSO_ALLOWED_UPSTREAMS`).
### Proxy — `ANY /v1/upstream/<upstream_key>/<path>`
- **`<upstream_key>`** : `orchestrator`, `repos_devtools`, `ia_dev_gateway`, `anythingllm_devtools`, `tools_bridge`, `langextract`, `regex_search`, `claw_proxy`, `local_office`.
- **`<path>`** : transmis à lURL de base du service (ex. `/v1/upstream/orchestrator/v1/...``http://127.0.0.1:37145/v1/...`).
- **Corps** : relayé (limite `GLOBAL_API_MAX_BODY_BYTES`, défaut 32 MiB).
- **Erreurs** : `401` si Bearer interne absent ou incorrect ; `404` si clé inconnue ; `503` si `local_office` sans `LOCAL_OFFICE_API_KEY`.
- **Erreurs** : `401` si Bearer interne absent ou incorrect ; `404` si clé inconnue ; `503` si jeton manquant pour lamont (ex. `ORCHESTRATOR_TOKEN`, `LOCAL_OFFICE_API_KEY`, etc.).
## Journaux

View File

@ -22,14 +22,14 @@ Vérifie le Bearer utilisateur. Réponse `200` : `{ "valid": true, "claims": { .
### `GET /v1/upstreams`
Liste les clés de proxy disponibles : `{ "upstreams": [ "orchestrator", ... ] }`.
Liste les clés de proxy disponibles (allowlist) : `{ "upstreams": [ "orchestrator", ... ] }`.
### Proxy — `ANY /proxy/<upstream_key>/<path>`
- **`<upstream_key>`** : voir liste ci-dessus (`repos_devtools`, `orchestrator`, etc.).
- **`<path>`** : relayé vers **smart-ide-global-api** sous `/v1/upstream/<upstream_key><path>` (ex. `/proxy/orchestrator/v1/...``GLOBAL_API_URL/v1/upstream/orchestrator/v1/...`).
- **Corps** : relayé pour les méthodes avec body (limite `SSO_GATEWAY_MAX_BODY_BYTES`, défaut 32 MiB).
- **Réponses derreur** : `401` si Bearer utilisateur absent ou invalide ; `404` si clé inconnue ; erreurs amont si lAPI globale ou un micro-service refuse la requête.
- **Réponses derreur** : `401` si Bearer utilisateur absent ou invalide ; `403` si lupstream est hors allowlist (`SSO_ALLOWED_UPSTREAMS`) ; `404` si route inconnue ; erreurs amont si lAPI globale ou un micro-service refuse la requête.
Len-tête `Authorization` utilisateur nest **pas** transmis à lAPI globale ; il est remplacé par `GLOBAL_API_INTERNAL_TOKEN`. Les claims OIDC sont transmis en `X-OIDC-Sub` / `X-OIDC-Email` jusquaux micro-services. Voir [sso-gateway-service.md](../features/sso-gateway-service.md) et [global-api.md](./global-api.md).
@ -51,11 +51,12 @@ Aucun stockage d**utilisateurs** ou de **comptes par projet** dans ce service
| `SSO_GATEWAY_HOST` / `SSO_GATEWAY_PORT` | Bind HTTP |
| `SSO_CORS_ORIGIN` | Si défini, en-têtes CORS sur les réponses |
| `SSO_GATEWAY_MAX_BODY_BYTES` | Taille max du corps en entrée |
| `SSO_ALLOWED_UPSTREAMS` | Allowlist des upstreams (CSV). Défaut: `orchestrator`. `*`/`all` pour autoriser tout. |
| `GLOBAL_API_URL` | Base HTTP de smart-ide-global-api (défaut `http://127.0.0.1:37149`) |
| `GLOBAL_API_INTERNAL_TOKEN` | Obligatoire — même valeur que sur smart-ide-global-api |
| `SMART_IDE_MONOREPO_ROOT` | Optionnel — racine pour écrire sous `.logs/sso-gateway/` |
Les jetons et hôtes des micro-services sont lus par **smart-ide-global-api** ; la liste des clés `GET /v1/upstreams` provient du module **`@4nk/smart-ide-upstreams`** (`packages/smart-ide-upstreams/`). Voir `config/services.local.env.example` et [global-api.md](./global-api.md).
Les jetons et hôtes des micro-services sont lus par **smart-ide-global-api** ; la liste des clés connues provient du module **`@4nk/smart-ide-upstreams`** (`packages/smart-ide-upstreams/`). `GET /v1/upstreams` applique ensuite `SSO_ALLOWED_UPSTREAMS`. Voir `config/services.local.env.example` et [global-api.md](./global-api.md).
## Voir aussi

View File

@ -26,8 +26,8 @@ Vue densemble et index complet : **[repo/README.md](./repo/README.md)**. Règ
| [repo/ia-dev-smart-ide-integration.md](./repo/ia-dev-smart-ide-integration.md) | Module `ia_dev` dans smart_ide |
| [repo/ia-dev-repository-overview.md](./repo/ia-dev-repository-overview.md) | Dépôt ia_dev : agents, deploy |
| [repo/ia-dev-project-conf-schema.md](./repo/ia-dev-project-conf-schema.md) | Schéma `conf.json`, résolution projet |
| [repo/ia-dev-deploy-lib.md](./repo/ia-dev-deploy-lib.md) | `ia_dev/deploy/lib/` |
| [repo/ia-dev-shared-lib.md](./repo/ia-dev-shared-lib.md) | `ia_dev/lib/project_config.sh` |
| [repo/ia-dev-deploy-lib.md](./repo/ia-dev-deploy-lib.md) | `IA_DEV_ROOT/deploy/lib/` |
| [repo/ia-dev-shared-lib.md](./repo/ia-dev-shared-lib.md) | `IA_DEV_ROOT/lib/project_config.sh` |
| [repo/service-*.md](./repo/README.md) | Exploitation de chaque micro-service (voir index `repo/README`) |
| [repo/script-anythingllm-pull-sync.md](./repo/script-anythingllm-pull-sync.md) | Hook post-merge → AnythingLLM |
| [repo/service-anythingllm-devtools.md](./repo/service-anythingllm-devtools.md) | Service HTTP AnythingLLM + devtools |

View File

@ -39,6 +39,23 @@ git clone https://github.com/lapce/lapce.git core_ide
(Ou lURL / remote interne retenu par léquipe ; SSH si configuré.)
Alternative (recommandé) : utiliser le script de dépôt, qui vérifie aussi les remotes :
```bash
./scripts/ensure-core-ide.sh
```
## Patches Smart IDE (Lapce)
Le dossier `core_ide/` est ignoré par Git côté monorepo. Les modifications Smart IDE appliquées à Lapce sont donc **versionnées sous forme de patches** dans :
- `patches/lapce/` (fichiers `*.patch` + liste ordonnée `series`)
Scripts associés :
- `./scripts/core-ide-apply-patches.sh` : applique `patches/lapce/series` sur `core_ide/`
- `./scripts/core-ide-export-patches.sh` : exporte les commits `core_ide` (base..HEAD) vers `patches/lapce/*.patch` et régénère `series`
### Migration depuis lancien emplacement
Si un clone Lapce existait sous `forks/lapce/`, le renommer une fois :

View File

@ -25,6 +25,18 @@ Lutilisateur travaille depuis un **Linux client** ; le **calcul**, les **mod
- **Local Office** : données sous `services/local-office/data/` (ou chemins surchargés par `STORAGE_PATH` / `DATABASE_PATH`) sur l**hôte qui exécute lAPI** ; à sauvegarder et à protéger comme toute instance de fichiers métier.
- Le client doit disposer dune **identité SSH** autorisée sur le serveur (voir `add-ssh-key.sh` et [infrastructure.md](./infrastructure.md)).
## Tunnels SSH (poste client)
Le poste client peut exposer localement les ports « loopback » du serveur via `ssh -L ...`.
Script daide (génère la commande à exécuter, sans la daemoniser) :
```bash
./scripts/smart-ide-ssh-tunnel-plan.sh --mode minimal
```
Ce script résout `--project/--env` via `projects/active-project.json` (local, gitignoré) ou variables, puis lit `projects/<id>/conf.json``smart_ide.remote_data_access.environments.<env>.ssh_host_alias`.
## Documentation liée
- Vision produit et envs : [platform-target.md](./platform-target.md)

View File

@ -8,7 +8,7 @@ Références complémentaires : [services-functional-scope.md](./services-functi
| Élément | Rôle | Où vit la vérité opérationnelle |
|---------|------|----------------------------------|
| **smart_ide** | Socle : doc, `services/*`, scripts, systemd, confs `ia_dev` (`./projects/<id>/conf.json`), module **`ia_dev/`**, journaux **`logs/`** | Dépôt Git **smart_ide** (forge interne) |
| **smart_ide** | Socle : doc, `services/*`, scripts, systemd, confs `ia_dev` (`./projects/<id>/conf.json`), module **`services/ia_dev/`** (via `IA_DEV_ROOT`), journaux **`logs/`** | Dépôt Git **smart_ide** (forge interne) |
| **Projets développés** | Code métier (docv, autres produits) : sources, builds, tests | **Autres** dépôts Git ; clones sur disque en dehors de `./projects/` (convention : répertoire frère `../projects/<nom>/` ou équivalent) |
| **Couche API IA** | Routage HTTP, auth, appels vers LLM, RAG, outils, agents | Processus sur l**hôte** (systemd, ports locaux) ; contrats décrits sous `docs/API/` |
| **Git (hôte)** | Historique des dépôts, hooks, branches par environnement | Chaque dépôt ; politique de branche documentée par projet |
@ -67,7 +67,7 @@ flowchart TB
- **Source de vérité** pour le code et la documentation versionnée des projets.
- **Branches** : alignement avec les environnements (test / pprod / prod) selon la politique du projet ; smart_ide documente les cibles dans [platform-target.md](./platform-target.md) et [deployment-target.md](./deployment-target.md).
- **Module `ia_dev`** : présent dans larborescence du dépôt **smart_ide** ; liens `ia_dev/projects/*` et scripts documentés ([ia_dev-module.md](./ia_dev-module.md), [repo/projects-directory.md](./repo/projects-directory.md)).
- **Module `ia_dev`** : présent dans larborescence du dépôt **smart_ide** sous `services/ia_dev/` ; liens `IA_DEV_ROOT/projects/*` et scripts documentés ([ia_dev-module.md](./ia_dev-module.md), [repo/projects-directory.md](./repo/projects-directory.md)).
### Ollama
@ -89,8 +89,8 @@ Objectif : après un changement **tracé dans Git**, les systèmes en aval (Anyt
### 4.1 Ordre de référence (nouvelle machine ou post-clone)
1. Cloner **smart_ide** : `git clone …` (le répertoire **`ia_dev/`** suit le même historique Git que le monorepo).
2. Recréer les liens `ia_dev/projects/<id>` si besoin : `./scripts/ensure-ia-dev-project-link.sh smart_ide` (ou le wrapper `ensure-ia-dev-smart-ide-project-link.sh`) — voir [repo/projects-directory.md](./repo/projects-directory.md).
1. Cloner **smart_ide** : `git clone …` (le répertoire **`services/ia_dev/`** suit le même historique Git que le monorepo).
2. Recréer les liens `IA_DEV_ROOT/projects/<id>` si besoin (ex. `services/ia_dev/projects/<id>`) : `./scripts/ensure-ia-dev-project-link.sh smart_ide` (ou le wrapper `ensure-ia-dev-smart-ide-project-link.sh`) — voir [repo/projects-directory.md](./repo/projects-directory.md).
3. Cloner les **projets applicatifs** à lemplacement convenu (ex. `../projects/<id>/`) et vérifier les chemins **absolus** dans `projects/<id>/conf.json` si `ia_dev` doit les piloter.
4. Démarrer **Ollama** et **AnythingLLM** sur lhôte ([services.md](./services.md)) ; créer les **workspaces** et noter les **slugs**.
5. Configurer lenvironnement de synchro AnythingLLM : `~/.config/4nk/anythingllm-sync.env` (URL, clé API) — ne pas commiter les secrets.
@ -104,13 +104,13 @@ Objectif : après un changement **tracé dans Git**, les systèmes en aval (Anyt
### 4.3 Cycle de travail sur smart_ide
1. `git pull` sur smart_ide (inclut les mises à jour sous **`ia_dev/`**).
2. Réexécuter **`ensure-ia-dev-project-link.sh`** pour chaque id versionné (`smart_ide`, `enso`, `builazoo`, …) si `ia_dev/projects/` a été réinitialisé.
1. `git pull` sur smart_ide (inclut les mises à jour sous **`services/ia_dev/`**).
2. Réexécuter **`ensure-ia-dev-project-link.sh`** pour chaque id versionné (`smart_ide`, `enso`, `builazoo`, …) si `IA_DEV_ROOT/projects/` a été réinitialisé.
3. Option : installer le même hook **post-merge** sur le dépôt **smart_ide** si un workspace AnythingLLM est dédié au monorepo (fichier `.anythingllm.json` + slug).
### 4.4 Agents, déploiement, ticketing (`ia_dev`)
- Exécution depuis la **racine** de `ia_dev/` ; résolution du projet : `IA_PROJECT_ID`, `--project`, `MAIL_TO`, `AI_AGENT_TOKEN` — voir [repo/ia-dev-project-conf-schema.md](./repo/ia-dev-project-conf-schema.md).
- Exécution depuis la **racine** de `IA_DEV_ROOT` (ex. `services/ia_dev/`) ; résolution du projet : `IA_PROJECT_ID`, `--project`, `MAIL_TO`, `AI_AGENT_TOKEN` — voir [repo/ia-dev-project-conf-schema.md](./repo/ia-dev-project-conf-schema.md).
- Les scripts **ne remplacent pas** Git : ils **lisent** `conf.json` pour savoir où sont les dépôts et comment déployer.
### 4.5 Cohérence « clone présent + workspace aligné »

View File

@ -1,33 +1,39 @@
# AnythingLLM — synchronisation après `git pull`
# AnythingLLM — sync after `git pull`
## Objectif
## Goal
Déclencher un envoi vers AnythingLLM des fichiers **modifiés ou ajoutés** par un `git pull` (merge fast-forward ou merge classique), sans action manuelle dans léditeur.
Upload files **added or modified** by a `git pull` (fast-forward or merge) to AnythingLLM without manual IDE actions.
## Impacts
## What it changes
- Chaque dépôt concerné peut installer un hook Git **`post-merge`** qui appelle `scripts/anythingllm-pull-sync/sync.mjs`.
- Les mêmes exclusions que **`.4nkaiignore`** (et quelques motifs système) sappliquent.
- Les suppressions ou renommages ne sont pas reflétés comme suppressions côté AnythingLLM dans cette version (upload uniquement).
- Each target repo can install a Git **`post-merge`** hook that calls `scripts/anythingllm-pull-sync/sync.mjs`.
- The same exclusions as **`.4nkaiignore`** (plus a few system patterns) apply.
- Deletions/renames are not mirrored as deletions in AnythingLLM in this version (upload only).
## Modifications (dépôt smart_ide)
## Implementation (smart_ide repo)
- `scripts/anythingllm-pull-sync/` : script Node (ESM), dépendance `ignore`, `package.json`, `README.md`.
- `scripts/install-anythingllm-post-merge-hook.sh` : pose le hook dans `.git/hooks/post-merge` avec le chemin absolu vers `sync.mjs`.
- `scripts/anythingllm-pull-sync/`: Node (ESM) script + dependency `ignore`.
- `scripts/install-anythingllm-post-merge-hook.sh`: installs `.git/hooks/post-merge` with an absolute path to `sync.mjs`.
## Configuration par dépôt
## Repo configuration (workspace slug)
- Fichier optionnel **`.anythingllm.json`** à la racine : `{ "workspaceSlug": "<slug>" }`.
- Ou variable denvironnement **`ANYTHINGLLM_WORKSPACE_SLUG`** (priorité documentée dans le README du script).
Slug resolution order (first match wins):
## Modalités de déploiement
1. `ANYTHINGLLM_WORKSPACE_SLUG` (env)
2. `.anythingllm.json` at repo root: `{ "workspaceSlug": "<slug>" }`
3. smart_ide `projects/<id>/conf.json` (matches `project_path` to the repo root; reads `smart_ide.anythingllm_workspace_slug[SMART_IDE_ENV]`, default env `test`)
1. Sur la machine de développement : `npm install` dans `scripts/anythingllm-pull-sync`.
2. Créer `~/.config/4nk/anythingllm-sync.env` avec `ANYTHINGLLM_BASE_URL` et `ANYTHINGLLM_API_KEY` (ne pas commiter la clé).
3. Exécuter `install-anythingllm-post-merge-hook.sh <chemin-du-repo>` pour chaque dépôt à synchroniser.
4. Sassurer quAnythingLLM (collector) est joignable depuis cette machine.
## Deployment on the host
## Modalités danalyse
1. Run `npm install` in `scripts/anythingllm-pull-sync`.
2. Create `~/.config/4nk/anythingllm-sync.env` with:
- `ANYTHINGLLM_BASE_URL`
- `ANYTHINGLLM_API_KEY`
3. Install the hook:
- per repo: `./scripts/install-anythingllm-post-merge-hook.sh /path/to/repo`
- or for configured clones: `./scripts/install-anythingllm-post-merge-hook.sh --all`
- Messages sur **stderr** : `uploaded=`, `skipped=`, `errors=`, détail des erreurs dupload (tronqué au-delà de 20 lignes).
- Si `ORIG_HEAD` est absent, ou si URL / clé / slug manquent : message explicite et **code de sortie 0** pour ne pas bloquer le pull.
## Observability
- stderr summary: `uploaded=`, `skipped=`, `errors=`, plus up to 20 error lines.
- If `ORIG_HEAD` is missing, or if URL/key/slug is missing: explicit message and exit code `0` (does not block the pull).

View File

@ -16,7 +16,7 @@ Pour chaque **projet logique** (ex. périmètre docv, autre produit) :
1. **Clone Git** : le dépôt applicatif doit être **déjà cloné** au même titre que les autres projets de lespace de travail, en général sous une **racine de clones** **distincte** du dossier `./projects/` du monorepo (voir [repo/projects-directory.md](../repo/projects-directory.md)) — convention fréquente : répertoire **frère** `../projects/<nom>/` par rapport à la racine `smart_ide`.
2. **AnythingLLM** : le projet doit être **rattaché à un workspace** AnythingLLM (un workspace par projet). Lalimentation du workspace repose sur un corpus **aligné sur les données déployées** : récupération via **SSH** depuis test / pprod / prod puis pipeline de synchro (voir [remote-deployed-data-ssh.md](./remote-deployed-data-ssh.md), [anythingllm-workspaces.md](../anythingllm-workspaces.md), scripts sous `scripts/`).
3. **Configuration ia_dev** : lorsquun id projet est enregistré pour les agents ou le ticketing, un `conf.json` peut être versionné sous **`smart_ide/projects/<id>/conf.json`** ; les scripts `ia_dev` y accèdent via le lien `ia_dev/projects/<id>` lorsque le script [`ensure-ia-dev-project-link.sh`](../../scripts/ensure-ia-dev-project-link.sh) `<id>` (ou le wrapper `ensure-ia-dev-smart-ide-project-link.sh` pour `smart_ide`) a été exécuté.
3. **Configuration ia_dev** : lorsquun id projet est enregistré pour les agents ou le ticketing, un `conf.json` peut être versionné sous **`smart_ide/projects/<id>/conf.json`** ; les scripts `ia_dev` y accèdent via le lien `IA_DEV_ROOT/projects/<id>` (ex. `services/ia_dev/projects/<id>`) lorsque le script [`ensure-ia-dev-project-link.sh`](../../scripts/ensure-ia-dev-project-link.sh) `<id>` (ou le wrapper `ensure-ia-dev-smart-ide-project-link.sh` pour `smart_ide`) a été exécuté.
## Flux cible (vue simplifiée)

View File

@ -0,0 +1,42 @@
# E2E browser mode (current + next)
## Current mode (manual / assisted)
Short-term E2E is **manual** and uses a terminal browser for fast feedback:
- **Carbonyl** for previewing the **test** URL without a GUI browser:
- script: `scripts/open-carbonyl-preview-test.sh`
- per project config: `projects/<id>/conf.json``smart_ide.preview_urls.test`
Typical workflow:
1. Deploy to `test` (project workflow / `ia_dev`).
2. Open the `test` URL in Carbonyl:
```bash
./scripts/open-carbonyl-preview-test.sh --project <id>
```
3. Validate critical flows manually (login, navigation, chat proxy calls).
## Optional next step (automation)
If manual Carbonyl + system browser is not sufficient, introduce a dedicated service `browser-automation-api` **only** when at least one criterion is met (see [browser-automation-criteria.md](./browser-automation-criteria.md)):
- agent-driven reproducible E2E with timeouts + domain allowlist
- controlled scraping (pre-approved URLs)
- headless visual regression on infra without GUI
- rendering capture (PDF/images) for internal pages
Constraints for the future service:
- isolated process (`services/browser-automation-api/`)
- queue + concurrency limits + strict timeouts
- **network allowlist** (no arbitrary browsing)
- Bearer auth (service-to-service) + URL logging
## Related docs
- [carbonyl-terminal-browser.md](./carbonyl-terminal-browser.md)
- [browser-automation-criteria.md](./browser-automation-criteria.md)

View File

@ -19,9 +19,7 @@ Remplacer à terme lappel **direct** au répertoire module [`ia_dev`](../ia_d
## Cohabitation avec le sous-module
Aujourdhui `./ia_dev` reste le **checkout canonique** sur lhôte. Le binaire `ia-dev-gateway` reçoit `IA_DEV_ROOT` (défaut : répertoire parent du service ou chemin absolu vers `./ia_dev`).
**Trajectoire** : module `ia_dev` dans le monorepo jusquà ce quun fork soit **vendored** ou **cloné par le service** au déploiement ; documentation de migration dans [ia_dev-module.md](../ia_dev-module.md).
Le binaire `ia-dev-gateway` reçoit `IA_DEV_ROOT` (chemin racine du checkout `ia_dev`). Si `IA_DEV_ROOT` nest pas défini, il tente une résolution locale dans le monorepo (priorité `./ia_dev`, puis `./services/ia_dev`).
## API (spécification)
@ -49,7 +47,13 @@ Les codes derreur **401/403/404/409/422** sont explicites ; pas de fallback s
## Implémentation
Le répertoire [`services/ia-dev-gateway/`](../../services/ia-dev-gateway/) contient un **serveur Node/TypeScript** (`npm run build && npm start`) : scan des agents `.md`, runs en mémoire avec statut stub `completed`, flux SSE minimal. Brancher le **runner** réel (`ia_dev` scripts) sur `POST /v1/runs` reste à faire. Lorchestrateur [orchestrator-api.md](./orchestrator-api.md) peut cibler ce service pour `agent.run`.
Le répertoire [`services/ia-dev-gateway/`](../../services/ia-dev-gateway/) contient un **serveur Node/TypeScript** (`npm run build && npm start`) :
- scan des agents `.md` depuis `IA_DEV_ROOT/.smartIde/agents`
- `POST /v1/runs` : **runner script-backed** (subset allowlist) qui spawn des scripts `bash` sous `IA_DEV_ROOT/` et stream `stdout/stderr` via SSE
- `GET /v1/runs/{runId}/events` : SSE avec replay (`Last-Event-ID`) + keep-alive
Lorchestrateur peut cibler ce service via lintent `agent.run`.
## Voir aussi

View File

@ -1,8 +1,8 @@
# Module `ia_dev` dans smart_ide
Le répertoire **`./ia_dev`** à la racine du monorepo **smart_ide** contient l**équipe dagents** (définitions sous `.smartIde/agents/`, `.smartIde/rules/`), **`deploy/`**, **`git-issues/`**, etc. Il est **versionné dans ce dépôt** (plus de sous-module Git séparé pour le checkout standard).
Le répertoire **`./services/ia_dev`** dans le monorepo **smart_ide** contient l**équipe dagents** (définitions sous `.smartIde/agents/`, `.smartIde/rules/`), **`deploy/`**, **`git-issues/`**, etc. Il est **versionné dans ce dépôt**.
Les **`conf.json` par projet** pour ce monorepo restent sous **`./projects/<id>/`** à la racine de **smart_ide** (voir [repo/projects-directory.md](./repo/projects-directory.md)), pas mélangés avec les clones applicatifs (`../projects/` ou autre). Des **liens symboliques** `ia_dev/projects/<id>` → `../../projects/<id>` (pour chaque id versionné, ex. `smart_ide`, `enso`, `builazoo`) permettent aux scripts `ia_dev` de résoudre les `conf.json` sous `projects/`. Après un clone neuf ou une réorganisation des dossiers:
Les **`conf.json` par projet** pour ce monorepo restent sous **`./projects/<id>/`** à la racine de **smart_ide** (voir [repo/projects-directory.md](./repo/projects-directory.md)), pas mélangés avec les clones applicatifs (`../projects/` ou autre). Des **liens symboliques** `services/ia_dev/projects/<id>` → `../../projects/<id>` (pour chaque id versionné, ex. `smart_ide`, `enso`, `builazoo`) permettent aux scripts `ia_dev` de résoudre les `conf.json` sous `projects/`. Après un clone neuf ou une réorganisation des dossiers:
```bash
./scripts/ensure-ia-dev-project-link.sh smart_ide
@ -12,12 +12,12 @@ Les **`conf.json` par projet** pour ce monorepo restent sous **`./projects/<id>/
Le script `ensure-ia-dev-smart-ide-project-link.sh` appelle `ensure-ia-dev-project-link.sh smart_ide`.
Lexécution des scripts reste **depuis la racine `ia_dev/`**, comme dans la documentation amont du dépôt historique [4nk/ia_dev](https://git.4nkweb.com/4nk/ia_dev.git) ; **smart_ide** fournit lenvironnement IDE, les scripts hôte, les unités systemd et les journaux sous `logs/` ([repo/logs-directory.md](./repo/logs-directory.md)).
Lexécution des scripts reste **depuis la racine `services/ia_dev/`**, comme dans la documentation amont du dépôt historique [4nk/ia_dev](https://git.4nkweb.com/4nk/ia_dev.git) ; **smart_ide** fournit lenvironnement IDE, les scripts hôte, les unités systemd et les journaux sous `logs/` ([repo/logs-directory.md](./repo/logs-directory.md)).
## Journaux
- Tirage Git planifié des clones : `logs/git-pull-projects.log` ([repo/logs-directory.md](./repo/logs-directory.md), via [`cron/git-pull-wrapper.sh`](../cron/git-pull-wrapper.sh)).
- Scripts `ia_dev` : `logs/ia_dev.log` ([repo/logs-directory.md](./repo/logs-directory.md), via [`ia_dev/lib/smart_ide_logs.sh`](../ia_dev/lib/smart_ide_logs.sh)).
- Scripts `ia_dev` : `logs/ia_dev.log` ([repo/logs-directory.md](./repo/logs-directory.md), via [`services/ia_dev/lib/smart_ide_logs.sh`](../services/ia_dev/lib/smart_ide_logs.sh)).
## Service dintégration
@ -28,14 +28,14 @@ Le périmètre «service» côté monorepo est documenté sous [repo/ia-de
| Élément | Rôle |
|---------|------|
| **smart_ide** | Cible UX IDE, scripts socle, systemd, doc de déploiement, **`logs/`** |
| **`ia_dev/`** (module dans ce dépôt) | Agents, déploiements, ticketing ; confs projet dans `./projects/` + liens sous `ia_dev/projects/` |
| **`services/ia_dev/`** (module dans ce dépôt) | Agents, déploiements, ticketing ; confs projet dans `./projects/` + liens sous `services/ia_dev/projects/` |
Le futur **agent gateway** doit traiter **`./ia_dev`** comme chemin canonique sur le serveur sauf configuration contraire. Voir [system-architecture.md](./system-architecture.md).
Le futur **agent gateway** doit traiter `IA_DEV_ROOT` comme chemin canonique sur le serveur (résolution par défaut : `./ia_dev` puis `./services/ia_dev`). Voir [system-architecture.md](./system-architecture.md).
## Trajectoire : service `ia-dev-gateway`
Un service HTTP dédié ([features/ia-dev-service.md](./features/ia-dev-service.md), [API/ia-dev-gateway.md](./API/ia-dev-gateway.md)) prendra le relais pour les **clients** (Lapce, front, orchestrateur) : le répertoire **`./ia_dev`** reste la **source de fichiers** côté hôte jusquà une éventuelle extraction ou conteneurisation documentée ailleurs.
Un service HTTP dédié ([features/ia-dev-service.md](./features/ia-dev-service.md), [API/ia-dev-gateway.md](./API/ia-dev-gateway.md)) prendra le relais pour les **clients** (Lapce, front, orchestrateur) : le répertoire référencé par **`IA_DEV_ROOT`** reste la **source de fichiers** côté hôte jusquà une éventuelle extraction ou conteneurisation documentée ailleurs.
1. **Phase actuelle** : module dans **smart_ide** + exécution manuelle / scripts depuis la racine `ia_dev`.
2. **Phase gateway** : binaire `ia-dev-gateway` sur lhôte, `IA_DEV_ROOT` pointant vers `./ia_dev`.
1. **Phase actuelle** : module dans **smart_ide** + exécution manuelle / scripts depuis la racine `services/ia_dev`.
2. **Phase gateway** : binaire `ia-dev-gateway` sur lhôte, `IA_DEV_ROOT` pointant vers `./services/ia_dev` (ou `./ia_dev` si présent).
3. **Phase fork / mirror** : le dépôt amont `ia_dev` peut continuer à exister sur la forge ; la copie de travail dans **smart_ide** suit le flux Git habituel du monorepo.

View File

@ -1,17 +1,17 @@
# Projet `ia_dev` : `smart_ide`
Le dépôt **smart_ide** est enregistré dans le sous-module **`ia_dev`** sous lidentifiant de projet **`smart_ide`**, pour les agents, le ticketing Gitea et la doc wiki alignés sur la forge **4nk/smart_ide**.
Le dépôt **smart_ide** est enregistré pour le module **`ia_dev`** (racine `IA_DEV_ROOT`, checkout intégré sous `services/ia_dev/`) sous lidentifiant de projet **`smart_ide`**, pour les agents, le ticketing Gitea et la doc wiki alignés sur la forge **4nk/smart_ide**.
## Fichier de configuration
- **Source de vérité (versionnée dans ce monorepo) :** [`projects/smart_ide/conf.json`](../projects/smart_ide/conf.json) — chemins machine (`project_path`), URLs wiki et issues (`https://git.4nkweb.com/4nk/smart_ide/...`), boîtes mail autorisées pour le ticketing (envs test / pprod / prod).
- **Sous-module `ia_dev` :** le chemin `ia_dev/projects/smart_ide/conf.json` doit résoudre le même fichier via le lien créé par [`scripts/ensure-ia-dev-project-link.sh`](../scripts/ensure-ia-dev-project-link.sh) `smart_ide` (wrapper : [`ensure-ia-dev-smart-ide-project-link.sh`](../scripts/ensure-ia-dev-smart-ide-project-link.sh)).
- **Module `ia_dev` :** le chemin `IA_DEV_ROOT/projects/smart_ide/conf.json` (ex. `services/ia_dev/projects/smart_ide/conf.json`) doit résoudre le même fichier via le lien créé par [`scripts/ensure-ia-dev-project-link.sh`](../scripts/ensure-ia-dev-project-link.sh) `smart_ide` (wrapper : [`ensure-ia-dev-smart-ide-project-link.sh`](../scripts/ensure-ia-dev-smart-ide-project-link.sh)).
Adapter **`project_path`** (et champs dérivés si vous ajoutez `build_dirs` / `deploy`) sur chaque poste ou serveur où `ia_dev` exécute des commandes sur ce dépôt. Les **clones** dautres apps (docv, etc.) ne vont **pas** dans `./projects/` : voir [repo/projects-directory.md](./repo/projects-directory.md).
## Agents Cursor (pont smart_ide → ia_dev)
Dans ce dépôt, les définitions **Cursor** sous [`.smartIde/agents/`](../.smartIde/agents/) utilisent le préfixe **`ia-dev-*`** : elles fixent le projet **`smart_ide`**, imposent dindiquer l**environnement** (`test`, `pprod`, `prod`), puis renvoient à la procédure complète dans le sous-module : `ia_dev/.smartIde/agents/<agent>.md`.
Dans ce dépôt, les définitions **Cursor** sous [`.smartIde/agents/`](../.smartIde/agents/) utilisent le préfixe **`ia-dev-*`** : elles fixent le projet **`smart_ide`**, imposent dindiquer l**environnement** (`test`, `pprod`, `prod`), puis renvoient à la procédure complète dans le module : `IA_DEV_ROOT/.smartIde/agents/<agent>.md` (ex. `services/ia_dev/.smartIde/agents/<agent>.md`).
| Agent Cursor (smart_ide) | Définition ia_dev |
|--------------------------|-------------------|
@ -33,9 +33,9 @@ Dans ce dépôt, les définitions **Cursor** sous [`.smartIde/agents/`](../.smar
| `ia-dev-notary-ai-process` | `notary-ai-process.md` |
| `ia-dev-closure-point-7-justification` | `closure-point-7-justification.md` |
Règle de contexte (fichiers sous `ia_dev/`, `docs/`, `services/`, etc.) : [`.smartIde/rules/smart-ide-ia-dev-bridge.mdc`](../.smartIde/rules/smart-ide-ia-dev-bridge.mdc).
Règle de contexte (fichiers sous `IA_DEV_ROOT/` (ex. `services/ia_dev/`), `docs/`, `services/`, etc.) : [`.smartIde/rules/smart-ide-ia-dev-bridge.mdc`](../.smartIde/rules/smart-ide-ia-dev-bridge.mdc).
**Usage :** choisir lagent `ia-dev-*` dans Cursor et préciser dans le message lenvironnement cible ; pour les scripts, `cd ia_dev` et `IA_PROJECT_ID=smart_ide` (ou `--project smart_ide`). Détail schéma conf : [repo/ia-dev-project-conf-schema.md](./repo/ia-dev-project-conf-schema.md). Conf **smart_ide** : `projects/smart_ide/conf.json` à la racine du monorepo.
**Usage :** choisir lagent `ia-dev-*` dans Cursor et préciser dans le message lenvironnement cible ; pour les scripts, `cd services/ia_dev` et `IA_PROJECT_ID=smart_ide` (ou `--project smart_ide`). Détail schéma conf : [repo/ia-dev-project-conf-schema.md](./repo/ia-dev-project-conf-schema.md). Conf **smart_ide** : `projects/smart_ide/conf.json` à la racine du monorepo.
## Liens

View File

@ -24,8 +24,8 @@ Toute la documentation **opérationnelle** qui vivait auparavant sous des `READM
| [ia-dev-smart-ide-integration.md](./ia-dev-smart-ide-integration.md) | Module `ia_dev` dans smart_ide, journaux, liens architecture |
| [ia-dev-repository-overview.md](./ia-dev-repository-overview.md) | Dépôt ia_dev : agents, scripts deploy, usage standalone |
| [ia-dev-project-conf-schema.md](./ia-dev-project-conf-schema.md) | Schéma `projects/<id>/conf.json`, résolution du projet, règles agents |
| [ia-dev-deploy-lib.md](./ia-dev-deploy-lib.md) | Bibliothèques partagées `ia_dev/deploy/lib/` |
| [ia-dev-shared-lib.md](./ia-dev-shared-lib.md) | `ia_dev/lib/project_config.sh` et résolution projet |
| [ia-dev-deploy-lib.md](./ia-dev-deploy-lib.md) | Bibliothèques partagées `IA_DEV_ROOT/deploy/lib/` |
| [ia-dev-shared-lib.md](./ia-dev-shared-lib.md) | `IA_DEV_ROOT/lib/project_config.sh` et résolution projet |
| **Services HTTP (exploitation)** | |
| [service-repos-devtools.md](./service-repos-devtools.md) | Clone / liste / load Git sous racine contrôlée |
| [service-anythingllm-devtools.md](./service-anythingllm-devtools.md) | AnythingLLM + repos-devtools + RAG initial (HTTP) |
@ -37,6 +37,7 @@ Toute la documentation **opérationnelle** qui vivait auparavant sous des `READM
| [service-langextract.md](./service-langextract.md) | Wrapper LangExtract |
| **Scripts et extensions** | |
| [script-anythingllm-pull-sync.md](./script-anythingllm-pull-sync.md) | Hook post-merge → upload AnythingLLM |
| [script-remote-data-ssh-sync.md](./script-remote-data-ssh-sync.md) | SSH pull deployed data → local mirror → optional AnythingLLM ingest |
| [service-carbonyl.md](./service-carbonyl.md) | Carbonyl (navigateur terminal), sous-module amont |
| [service-pageindex.md](./service-pageindex.md) | PageIndex (index sémantique vectorless), sous-module amont |
| [service-chandra.md](./service-chandra.md) | Chandra OCR, sous-module amont |

View File

@ -1,9 +1,9 @@
# Bibliothèques partagées `ia_dev/deploy/lib/`
# Bibliothèques partagées `IA_DEV_ROOT/deploy/lib/`
## `ssh.sh`
Helpers SSH/SCP canoniques (`ssh_run`, `scp_copy`, `require_ssh_key`, `ssh_common_opts`).
**LeCoffre** : `deploy/scripts_v2/_lib/ssh.sh` du projet peut sourcer `ia_dev/deploy/lib/ssh.sh` lorsque ce chemin existe depuis la racine du monorepo.
**LeCoffre** : `deploy/scripts_v2/_lib/ssh.sh` du projet peut sourcer `IA_DEV_ROOT/deploy/lib/ssh.sh` lorsque ce chemin existe depuis la racine du monorepo.
## `deploy-log.sh`

View File

@ -1,13 +1,13 @@
# Schéma `projects/<id>/conf.json` (ia_dev)
Ce document est la **copie canonique** dans **smart_ide** du schéma de configuration ia_dev. Le fichier amont peut exister sous **`ia_dev/projects/README.md`** dans un checkout qui suit le dépôt ia_dev seul.
Ce document est la **copie canonique** dans **smart_ide** du schéma de configuration ia_dev. Le fichier amont peut exister sous **`IA_DEV_ROOT/projects/README.md`** (ex. `services/ia_dev/projects/README.md`) dans un checkout qui suit le dépôt ia_dev seul.
Le dépôt **ia_dev** est un **dépôt autonome**. Les paramètres par projet sont dans `projects/<id>/conf.json`. Le **`<id>`** est le nom du répertoire sous `projects/`.
**Chemins dans conf.json**
Les scripts dans `deploy/` déploient les **projets configurés** dans leurs répertoires ; ils ne déploient pas ia_dev.
- **Chemins projet / deploy** (`project_path`, `deploy.repository_root`, etc.) : **absolus** ou **relatifs à la racine du monorepo smart_ide**. Résolution : `ia_dev/lib/conf_path_resolve.sh` lorsque la conf vit sous `…/projects/<id>/conf.json` ou `…/ia_dev/projects/<id>/conf.json`.
- **Chemins projet / deploy** (`project_path`, `deploy.repository_root`, etc.) : **absolus** ou **relatifs à la racine du monorepo smart_ide**. Résolution : `IA_DEV_ROOT/lib/conf_path_resolve.sh` (ex. `services/ia_dev/lib/conf_path_resolve.sh`) lorsque la conf vit sous `…/projects/<id>/conf.json` ou `…/IA_DEV_ROOT/projects/<id>/conf.json`.
- **`build_dirs`** : **absolu** ; **relatif au monorepo** si la valeur commence par `../` ; sinon **relatif à la racine Git du projet** (`repository_root`).
- **`version.package_json_paths`** : **relatif à la racine du dépôt projet** sauf absolu.
- **Relatif à la racine ia_dev** : `mail.imap_bridge_env`, `git.token_file` → fichiers sous `.secrets/` de ia_dev.
@ -34,13 +34,13 @@ Les agents ne modifient pas `projects/<id>/conf.json` sans validation humaine ex
| `name` | no | Nom lisible. |
| `project_path` | no | Racine Git du clone pour cron / outillage. |
| `build_dirs` | no | Répertoires `npm run build` (règles de relatif / absolu ci-dessus). |
| `deploy.*` | no | Chemins scripts, secrets, orchestrateur — voir tableau complet dans lhistorique Git de ce fichier ou `ia_dev/projects/README.md` amont. |
| `deploy.*` | no | Chemins scripts, secrets, orchestrateur — voir tableau complet dans lhistorique Git de ce fichier ou `IA_DEV_ROOT/projects/README.md` amont. |
| `deploy.host_stays_on_test` | no | Comportement `deploy-by-script-to.sh` (branche test vs pprod/prod). |
| `tickets` | no | URL issues, `authorized_emails` ; le **to** sert à résoudre le projet. |
| `cron` | no | Extension **smart_ide** : `{ "git_pull": false }` pour désactiver le pull planifié. |
| `smart_ide` | no | Extension **smart_ide** : `remote_data_access`, `anythingllm_workspace_slug`, `workspace` (`folders` + `settings`, équivalent `.code-workspace` ; y placer `smartIde.activeProjectId`), `preview_urls` (`test`, … URLs pour prévisualisation ex. Carbonyl), etc. |
Détail ticketing : `ia_dev/projects/ia_dev/docs/TICKETS_SPOOL_FORMAT.md`.
Détail ticketing : `IA_DEV_ROOT/projects/ia_dev/docs/TICKETS_SPOOL_FORMAT.md`.
**.secrets à la racine ia_dev** : `token`, `git-issues/agent-loop.env`, `git-issues/imap-bridge.env`.

View File

@ -6,29 +6,29 @@ Dépôt de pilotage par l'IA pour les projets : **équipe d'agents IA** dont le
## Usage (standalone)
- **Racine d'exécution** : tous les scripts sont lancés depuis la **racine de ia_dev** (ce dépôt). L'id projet est résolu par **MAIL_TO**, **AI_AGENT_TOKEN**, **`IA_PROJECT_ID`**, **`--project`**, ou premier argument selon le script (voir [ia-dev-project-conf-schema.md](./ia-dev-project-conf-schema.md)).
- **Config** : dans `projects/<id>/conf.json`, les chemins vers les dépôts projet peuvent être **absolus** ou **relatifs à la racine du monorepo smart_ide** lorsque ia_dev y est intégré (`lib/conf_path_resolve.sh`). Les champs `mail.imap_bridge_env` et `git.token_file` sont **relatifs à la racine de ia_dev**. Le répertoire `.secrets` à la racine de ia_dev contient `token` et `git-issues/agent-loop.env`, `git-issues/imap-bridge.env`.
- **Racine d'exécution** : tous les scripts sont lancés depuis la **racine `IA_DEV_ROOT`**. L'id projet est résolu par **MAIL_TO**, **AI_AGENT_TOKEN**, **`IA_PROJECT_ID`**, **`--project`**, ou premier argument selon le script (voir [ia-dev-project-conf-schema.md](./ia-dev-project-conf-schema.md)).
- **Config** : dans `projects/<id>/conf.json`, les chemins vers les dépôts projet peuvent être **absolus** ou **relatifs à la racine du monorepo smart_ide** lorsque ia_dev y est intégré (`lib/conf_path_resolve.sh`). Les champs `mail.imap_bridge_env` et `git.token_file` sont **relatifs à `IA_DEV_ROOT`**. Le répertoire `.secrets` à la racine de `IA_DEV_ROOT` contient `token` et `git-issues/agent-loop.env`, `git-issues/imap-bridge.env`.
## Agents et domaines
Les **agents** ont leur **code et définitions** dans ia_dev (`.smartIde/agents/`, `.smartIde/rules/`) et sont **lancés de façon centralisée** depuis ce dépôt pour **tous les projets**. Ils sont **dédiés aux projets configurés** : ils agissent sur ces projets (doc, code, déploiement, ticketing), pas sur ia_dev.
Chaque agent indique où se trouve la doc : **projets gérés**`projects/<id>/docs` ; **ia_dev**`ia_dev/projects/ia_dev/docs` (copie embarquée selon checkout).
Chaque agent indique où se trouve la doc : **projets gérés**`projects/<id>/docs` ; **ia_dev**`IA_DEV_ROOT/projects/ia_dev/docs` (copie embarquée selon checkout).
| Domaine | Agents / composants |
|---------|---------------------|
| **Doc** | `docupdate` ; `ia_dev/projects/ia_dev/docs/` ; migration wiki (`git-issues/wiki-migrate-docs.sh`). |
| **Doc** | `docupdate` ; `IA_DEV_ROOT/projects/ia_dev/docs/` ; migration wiki (`git-issues/wiki-migrate-docs.sh`). |
| **Code** | `fix`, `evol`, `code`, `fix-search` ; workflow correctifs/évolutions. |
| **Ticketing** | `git-issues-process`, `agent-loop` ; spooler `projects/<id>/data/issues` ; scripts `git-issues/`. |
| **IA notaire (ai_working_help)** | `notary-ai-loop`, `notary-ai-process` ; API `ai_working_help/server.js` ; spooler `projects/<id>/data/notary-ai/{pending,responded}`. |
| **DevOps** | `push-by-script`, `deploy-by-script`, `deploy-pprod-or-prod`, `branch-align-by-script-from-test`, `change-to-all-branches` ; scripts `deploy/`. |
| **Sécurité / Qualité** | Règles `.smartIde/rules/` ; pas de secrets en dur ; `fix-lint` ; clôture obligatoire (`.smartIde/rules/cloture-evolution.mdc`). |
Référence détaillée : `ia_dev/projects/ia_dev/docs/GIT_ISSUES_SCRIPTS_AGENTS.md`. Index : `ia_dev/projects/ia_dev/docs/README.md`.
Référence détaillée : `IA_DEV_ROOT/projects/ia_dev/docs/GIT_ISSUES_SCRIPTS_AGENTS.md`. Index : `IA_DEV_ROOT/projects/ia_dev/docs/README.md`.
## Répertoire d'exécution (standalone)
Tous les scripts sont invoqués depuis la **racine de ia_dev**.
Tous les scripts sont invoqués depuis la **racine `IA_DEV_ROOT`**.
- **deploy/** : déploient les **projets configurés**, pas ia_dev.
- **git-issues/** : logs et data par projet sous `projects/<id>/logs/` et `projects/<id>/data/issues/`.

View File

@ -1,10 +1,10 @@
# Bibliothèque partagée `ia_dev/lib/`
# Bibliothèque partagée `IA_DEV_ROOT/lib/`
## `project_config.sh`
Sourcé par les scripts **deploy** et **git-issues** pour résoudre l**id** projet et le chemin vers son JSON.
**Usage standalone** : exécution depuis la racine **ia_dev** ; définir **`IA_DEV_ROOT`** avant source si besoin.
**Usage standalone** : exécution depuis la racine **`IA_DEV_ROOT`** (ex. `services/ia_dev/` dans smart_ide).
**Après source** : `PROJECT_ID`, `PROJECT_CONFIG_PATH` (souvent `projects/<id>/conf.json`). Avec résolution par token : `PROJECT_ENV`.

View File

@ -1,15 +1,17 @@
# ia_dev — module smart_ide (`services/ia_dev/` + `ia_dev/`)
# ia_dev — module smart_ide (`services/ia_dev/`)
Le répertoire **`ia_dev/`** à la racine du monorepo **smart_ide** est le **module agents / déploiement / ticketing** (équivalent historique du dépôt [4nk/ia_dev](https://git.4nkweb.com/4nk/ia_dev.git)). Il est **versionné dans ce dépôt**.
Le répertoire **`services/ia_dev/`** dans le monorepo **smart_ide** est le **module agents / déploiement / ticketing** (équivalent historique du dépôt [4nk/ia_dev](https://git.4nkweb.com/4nk/ia_dev.git)). Il est **versionné dans ce dépôt**.
La racine du checkout `ia_dev` est traitée comme **`IA_DEV_ROOT`** par les scripts et services. Par défaut, les services tentent `./ia_dev` puis `./services/ia_dev` si `IA_DEV_ROOT` nest pas défini.
## Rôle
- Scripts **`ia_dev/deploy/`**, **`ia_dev/git-issues/`**, outillage **`ia_dev/tools/`**, définitions **`ia_dev/.smartIde/`**.
- Résolution des projets via **`projects/<id>/conf.json`** à la racine **smart_ide** et liens sous `ia_dev/projects/` (voir [projects-directory.md](./projects-directory.md), [ia_dev-module.md](../ia_dev-module.md)).
- Scripts **`IA_DEV_ROOT/deploy/`**, **`IA_DEV_ROOT/git-issues/`**, outillage **`IA_DEV_ROOT/tools/`**, définitions **`IA_DEV_ROOT/.smartIde/`**.
- Résolution des projets via **`projects/<id>/conf.json`** à la racine **smart_ide** et liens sous `IA_DEV_ROOT/projects/` (voir [projects-directory.md](./projects-directory.md), [ia_dev-module.md](../ia_dev-module.md)).
## Journaux smart_ide
Les exécutions shell concernées écrivent dans **`logs/ia_dev.log`** à la racine **smart_ide** lorsque la détection du monorepo réussit. Détail : [logs-directory.md](./logs-directory.md), implémentation `ia_dev/lib/smart_ide_logs.sh`.
Les exécutions shell concernées écrivent dans **`logs/ia_dev.log`** à la racine **smart_ide** lorsque la détection du monorepo réussit. Détail : [logs-directory.md](./logs-directory.md), implémentation `services/ia_dev/lib/smart_ide_logs.sh`.
## Variables (référence)

View File

@ -7,13 +7,13 @@ Le répertoire **`logs/`** est **versionné** comme conteneur (fichiers `README.
| Fichier | Origine |
|---------|---------|
| `git-pull-projects.log` | Tirage Git planifié (`cron/git-pull-wrapper.sh`), variable `PULL_SYNC_LOG` dans `cron/config.env` |
| `ia_dev.log` | Exécutions shell sous `ia_dev/` lorsque le checkout est détecté comme monorepo **smart_ide** (`cron/git-pull-wrapper.sh` ou `projects/smart_ide/` au-dessus de `ia_dev/`) |
| `ia_dev.log` | Exécutions shell sous `services/ia_dev/` (ou `ia_dev/` si présent) lorsque le checkout est détecté comme monorepo **smart_ide** (détection en remontant vers `cron/git-pull-wrapper.sh` ou `projects/smart_ide/`) |
Variable interne : **`SMART_IDE_LOG_IA_DEV_ROOT`** (racine `ia_dev`), posée par `ia_dev/lib/smart_ide_logs.sh`.
Variable interne : **`SMART_IDE_LOG_IA_DEV_ROOT`** (racine ia_dev), posée par `services/ia_dev/lib/smart_ide_logs.sh`.
## Intégration
Contrat service : [ia-dev-smart-ide-integration.md](./ia-dev-smart-ide-integration.md), implémentation `ia_dev/lib/smart_ide_logs.sh`.
Contrat service : [ia-dev-smart-ide-integration.md](./ia-dev-smart-ide-integration.md), implémentation `services/ia_dev/lib/smart_ide_logs.sh`.
Configuration du pull planifié : [cron-git-pull.md](./cron-git-pull.md).

View File

@ -9,23 +9,23 @@ Les **sous-répertoires** `projects/<id>/` non listés dans le **`.gitignore`**
Les dépôts sources des produits (ex. backend **docv** sous un chemin du type `…/enso/docv`, autres apps) doivent vivre **ailleurs**, selon la convention du poste — typiquement un répertoire **frère** du monorepo, par ex. **`../projects/<nom>/`** (relatif à la racine `smart_ide`), **distinct** de `./projects/` ici.
- **`./projects/`** → **un seul fichier de configuration par id** : `projects/<id>/conf.json` (y compris le gabarit [`projects/example/conf.json`](../../projects/example/conf.json)). Pas de fichier `.code-workspace` versionné à côté : léquivalent multi-root IDE est **`smart_ide.workspace`** dans ce même `conf.json`. `ia_dev` résout via le lien symbolique décrit dans [ia_dev-module.md](../ia_dev-module.md).
- **`../projects/`** (ou autre racine configurée) → arborescences Git complètes, builds, etc. ; dans chaque `conf.json`, **`project_path`** et les chemins **`deploy.*`** utiles sont **relatifs à la racine du monorepo smart_ide** (ex. `../enso`, `.`) ou **absolus** ; le script `cron/git-pull-project-clones.sh` et ia_dev les résolvent depuis cette racine (`ia_dev/lib/conf_path_resolve.sh`).
- **`../projects/`** (ou autre racine configurée) → arborescences Git complètes, builds, etc. ; dans chaque `conf.json`, **`project_path`** et les chemins **`deploy.*`** utiles sont **relatifs à la racine du monorepo smart_ide** (ex. `../enso`, `.`) ou **absolus** ; le script `cron/git-pull-project-clones.sh` et ia_dev les résolvent depuis cette racine (`IA_DEV_ROOT/lib/conf_path_resolve.sh`).
## `smart_ide`
- Fichier : `projects/smart_ide/conf.json`
- Après clone ou réorganisation des dossiers : `./scripts/ensure-ia-dev-project-link.sh smart_ide` (ou le wrapper `scripts/ensure-ia-dev-smart-ide-project-link.sh`) pour recréer le lien `ia_dev/projects/smart_ide` → `../../projects/smart_ide`.
- Après clone ou réorganisation des dossiers : `./scripts/ensure-ia-dev-project-link.sh smart_ide` (ou le wrapper `scripts/ensure-ia-dev-smart-ide-project-link.sh`) pour recréer le lien sous `IA_DEV_ROOT/projects/smart_ide` (ex. `services/ia_dev/projects/smart_ide`)`../../projects/smart_ide` (chemin relatif variant selon `IA_DEV_ROOT`).
## `enso`
- Fichier : `projects/enso/conf.json` — clone **enso** frère du monorepo (`project_path` typique `../enso`), déploiement `deploy/scripts_v2`, forge **4nk/enso** (wiki / issues), mails ticketing `AI.ENSO.*@4nkweb.com`.
- Chemins **absolus sur les serveurs** sous **`smart_ide.remote_data_access`** : alignés sur **`ENSO_REMOTE_ROOT`**, **`ENSO_SSH_HOST`** et **`data/dossiers-permanents`** (dépôt enso, `enso-deploy.env`). Valeurs réelles : fichiers **`enso-deploy.env`** non versionnés.
- Cron fragment : `cron/fragments/enso.cron`
- Pour **`ia_dev`** : lien symbolique `ia_dev/projects/enso` → `../../projects/enso` (recréer avec `./scripts/ensure-ia-dev-project-link.sh enso`).
- Pour **`ia_dev`** : lien symbolique `IA_DEV_ROOT/projects/enso` → `../../projects/enso` (recréer avec `./scripts/ensure-ia-dev-project-link.sh enso` ; chemin relatif variant selon `IA_DEV_ROOT`).
## `builazoo`
- Fichier : `projects/builazoo/conf.json` — dépôt **sous la racine monorepo** (`project_path` : `builazoo`, soit `smart_ide/builazoo/`), forge **4nk/builazoo** (wiki / issues à ajuster si le dépôt diffère), mails ticketing `AI.BUILAZOO.*@4nkweb.com`.
- Fichier : `projects/builazoo/conf.json` — dépôt **frère du monorepo** (`project_path` typique `../builazoo`), forge **4nk/builazoo** (wiki / issues à ajuster si le dépôt diffère), mails ticketing `AI.BUILAZOO.*@4nkweb.com`.
- **`smart_ide.remote_data_access`** : alias SSH `builazoo-test` / `builazoo-pprod` / `builazoo-prod` (à déclarer dans `~/.ssh/config` comme pour les autres ids).
- Multi-root IDE : **`smart_ide.workspace`** dans `conf.json` (dossiers + `smartIde.activeProjectId`).
- Cron fragment : `cron/fragments/builazoo.cron`
@ -61,4 +61,4 @@ Convention agents : `.smartIde/rules/smart-ide-ia-dev-bridge.mdc`.
## Référence amont (schéma conf)
Schéma détaillé des champs `conf.json` : [ia-dev-project-conf-schema.md](./ia-dev-project-conf-schema.md) (aligné sur `ia_dev/projects/README.md` amont). Extensions **`cron`** et **`smart_ide`** : spécifiques smart_ide ; `ia_dev` peut ignorer les champs non lus.
Schéma détaillé des champs `conf.json` : [ia-dev-project-conf-schema.md](./ia-dev-project-conf-schema.md) (aligné sur `IA_DEV_ROOT/projects/README.md` amont). Extensions **`cron`** et **`smart_ide`** : spécifiques smart_ide ; `ia_dev` peut ignorer les champs non lus.

View File

@ -1,51 +1,77 @@
# anythingllm-pull-sync (`scripts/anythingllm-pull-sync/`)
Sexécute après **`git pull`** via le hook Git **`post-merge`** : envoie les **fichiers modifiés** entre `ORIG_HEAD` et `HEAD` vers un workspace AnythingLLM (`POST /api/v1/document/upload`).
Triggered after `git pull` via the Git `post-merge` hook: uploads files changed between `ORIG_HEAD` and `HEAD` to an AnythingLLM workspace (`POST /api/v1/document/upload`).
## Prérequis
## Requirements
- Processeur de documents AnythingLLM en ligne.
- Mêmes règles **`.4nkaiignore`** que lextension VS Code (racine du dépôt cible).
- Variables denvironnement ou fichier **`repo/.anythingllm.json`** (`workspaceSlug`).
- AnythingLLM document processor reachable from the host.
- Same `.4nkaiignore` rules as the legacy IDE extension (in the target repo root).
## Variables
## Environment
| Variable | Obligatoire | Description |
|----------|-------------|-------------|
| `ANYTHINGLLM_BASE_URL` | oui | Sans `/` final |
| `ANYTHINGLLM_API_KEY` | oui | Clé API développeur |
| `ANYTHINGLLM_WORKSPACE_SLUG` | non* | Slug du workspace |
| `ANYTHINGLLM_SYNC_MAX_FILES` | non | Défaut `200` |
| `ANYTHINGLLM_SYNC_MAX_FILE_BYTES` | non | Défaut `5242880` |
The generated hook sources `~/.config/4nk/anythingllm-sync.env` if present.
\* Si absent : lecture de **`repo/.anythingllm.json`**.
Required variables:
Fichier optionnel **`~/.config/4nk/anythingllm-sync.env`** sourcé par le hook généré.
- `ANYTHINGLLM_BASE_URL` (no trailing `/`)
- `ANYTHINGLLM_API_KEY`
## Installation du hook sur un clone
Optional variables:
- `ANYTHINGLLM_SYNC_MAX_FILES` (default `200`)
- `ANYTHINGLLM_SYNC_MAX_FILE_BYTES` (default `5242880`)
- `SMART_IDE_ENV` (`test|pprod|prod`, default `test`) for smart_ide project config resolution (see below)
## Workspace slug resolution
Order (first match wins):
1. `ANYTHINGLLM_WORKSPACE_SLUG` (env)
2. `repo/.anythingllm.json` with `{ "workspaceSlug": "…" }`
3. smart_ide `projects/<id>/conf.json`:
- finds the project by matching `project_path` (resolved relative to the smart_ide root) to `--repo-root`
- reads `smart_ide.anythingllm_workspace_slug[SMART_IDE_ENV]` (default env `test`)
If no slug can be resolved, the script prints an explicit message and exits with code `0` (does not block the pull).
## Installing the hook
Single repo:
```bash
/path/vers/smart_ide/scripts/install-anythingllm-post-merge-hook.sh /path/vers/repo-cible
./scripts/install-anythingllm-post-merge-hook.sh /path/to/repo
```
Une fois par machine, depuis ce dépôt :
All configured project clones (from `projects/*/conf.json`):
```bash
./scripts/install-anythingllm-post-merge-hook.sh --all
```
Single configured project:
```bash
./scripts/install-anythingllm-post-merge-hook.sh --project enso
```
One-time setup on the host (from this repo):
```bash
cd scripts/anythingllm-pull-sync && npm install
```
## Comportement
## Behavior
- Uniquement les chemins de `git diff --name-only --diff-filter=ACMRT ORIG_HEAD HEAD`.
- Si `ORIG_HEAD` ou config manque → **exit 0** avec message (ne bloque pas le pull).
- Pas de suppression miroir des fichiers supprimés dans AnythingLLM dans cette version (upload seul).
- Only uploads paths from `git diff --name-only --diff-filter=ACMRT ORIG_HEAD HEAD`.
- If `ORIG_HEAD` is missing, or if AnythingLLM config is missing: explicit message, exit `0`.
- Deletions/renames are not mirrored as deletions in AnythingLLM in this version (upload only).
## Désinstallation
## Uninstall
```bash
rm -f /path/vers/repo/.git/hooks/post-merge
rm -f /path/to/repo/.git/hooks/post-merge
```
## Liens
## Links
[features/anythingllm-pull-sync-after-pull.md](../features/anythingllm-pull-sync-after-pull.md), [anythingllm-workspaces.md](../anythingllm-workspaces.md), [service-anythingllm-devtools.md](./service-anythingllm-devtools.md).

View File

@ -0,0 +1,61 @@
# remote-data-ssh-sync (`scripts/remote-data-ssh-sync.sh`)
Pulls **deployed environment data** over SSH into a **local mirror** (not versioned in Git), then optionally ingests that mirror into **AnythingLLM**.
## Configuration source (per project)
`projects/<id>/conf.json`:
- `smart_ide.remote_data_access.environments.<env>.ssh_host_alias`
- `smart_ide.remote_data_access.environments.<env>.remote_data_directories[]`
- `smart_ide.anythingllm_workspace_slug[env]` (optional; required for ingestion)
## Mirror location
Default:
- `<smart_ide_root>/.data/remote-data/<projectId>/<env>/<role>/`
This directory is ignored by Git (see `.gitignore`).
Override:
- `SMART_IDE_REMOTE_DATA_MIRROR_ROOT=/abs/path`
## AnythingLLM ingestion
By default, the script attempts ingestion and skips explicitly if config is missing.
Inputs:
- `~/.config/4nk/anythingllm-sync.env` (optional): provides `ANYTHINGLLM_BASE_URL` + `ANYTHINGLLM_API_KEY`
- `projects/<id>/conf.json`: provides the workspace slug for the selected env
Implementation:
- calls `scripts/anythingllm-pull-sync/sync.mjs` with `--upload-all` on each mirrored role directory
## Usage
```bash
./scripts/remote-data-ssh-sync.sh --project enso --env test
```
Fetch only (no ingestion):
```bash
./scripts/remote-data-ssh-sync.sh --project enso --env test --no-anythingllm
```
Ingest only specific roles:
```bash
./scripts/remote-data-ssh-sync.sh --project enso --env test --roles docv_dp_git_data
```
Dry-run (prints rsync command lines):
```bash
./scripts/remote-data-ssh-sync.sh --project enso --env test --dry-run
```

View File

@ -1,6 +1,6 @@
# ia-dev-gateway (`services/ia-dev-gateway/`)
API HTTP pour le checkout **ia_dev** : liste des agents (`.smartIde/agents/*.md`), `POST /v1/runs` (complétion stub), SSE sur `/v1/runs/:id/events`. Branchement futur sur les scripts deploy / agents réels.
HTTP API for the **ia_dev** checkout: agent registry (`.smartIde/agents/*.md`), `POST /v1/runs` (script-backed runner), and SSE streaming on `/v1/runs/:id/events`.
## Build / run
@ -9,12 +9,47 @@ cd services/ia-dev-gateway
npm install
npm run build
export IA_DEV_GATEWAY_TOKEN='your-secret'
# optionnel : IA_DEV_ROOT=/chemin/vers/ia_dev
# optional: IA_DEV_ROOT=/absolute/path/to/ia_dev
npm start
```
Écoute par défaut : **`127.0.0.1:37144`**.
## IA_DEV_ROOT resolution
If `IA_DEV_ROOT` is not set, the gateway resolves it in this order:
- `./ia_dev`
- `./services/ia_dev`
When using `./services/ia_dev`, you typically need to create project links so scripts can resolve `projects/<id>/conf.json`:
```bash
./scripts/ensure-ia-dev-project-link.sh smart_ide
./scripts/ensure-ia-dev-project-link.sh enso
./scripts/ensure-ia-dev-project-link.sh builazoo
```
## Script-backed runner (current)
The v1 runner executes a subset of agent IDs by spawning `bash` scripts under `IA_DEV_ROOT/deploy/` and streaming stdout/stderr as SSE events.
Supported agent IDs:
- `change-to-all-branches``deploy/change-to-all-branches.sh`
- `branch-align-by-script-from-test``deploy/branch-align.sh` (defaults to `env=test` if omitted)
- `deploy-by-script``deploy/deploy.sh` (env `test`) or `deploy/deploy-by-script-to.sh` (env `pprod|prod`)
- `push-by-script``deploy/pousse.sh`
- `site-generate``tools/site-generate.sh`
### `payload` conventions
- **`payload.args`**: `string[]` appended to the script arguments.
- **`payload.stdin`**: `string` written to the script stdin.
- **`payload.commitMessage`**: `string` alias for stdin for `push-by-script`.
- **`payload.remote`**: `string` passed as `--remote <remote>` for `push-by-script`.
- **`payload.bumpVersion`**: `boolean` adds `--bump-version` for `push-by-script`.
## Contrats
[API/ia-dev-gateway.md](../API/ia-dev-gateway.md), [features/ia-dev-service.md](../features/ia-dev-service.md).

View File

@ -27,7 +27,7 @@ Voir [anythingllm-workspaces.md](../anythingllm-workspaces.md) et [script-anythi
## Module `ia_dev`
Le répertoire **`ia_dev/`** contient l**équipe dagents**, les scripts `deploy/`, le ticketing Gitea, etc. (référence forge : [**ia_dev**](https://git.4nkweb.com/4nk/ia_dev.git)). Les **`conf.json`** pour ce monorepo sont sous **`projects/<id>/`** (voir [projects-directory.md](./projects-directory.md)). Détail : [ia_dev-module.md](../ia_dev-module.md), [ia-dev-smart-ide-integration.md](./ia-dev-smart-ide-integration.md), [ia-dev-repository-overview.md](./ia-dev-repository-overview.md), [ia_dev-project-smart_ide.md](../ia_dev-project-smart_ide.md).
Le répertoire **`services/ia_dev/`** (racine `IA_DEV_ROOT`) contient l**équipe dagents**, les scripts `deploy/`, le ticketing Gitea, etc. (référence forge : [**ia_dev**](https://git.4nkweb.com/4nk/ia_dev.git)). Les **`conf.json`** pour ce monorepo sont sous **`projects/<id>/`** (voir [projects-directory.md](./projects-directory.md)). Détail : [ia_dev-module.md](../ia_dev-module.md), [ia-dev-smart-ide-integration.md](./ia-dev-smart-ide-integration.md), [ia-dev-repository-overview.md](./ia-dev-repository-overview.md), [ia_dev-project-smart_ide.md](../ia_dev-project-smart_ide.md).
## Documentation centralisée

View File

@ -19,7 +19,7 @@ Conséquences :
- Les répertoires sous `services/` font partie du **même cycle de vie** que le reste du monorepo (revue, déploiement, systemd).
- **`core_ide/`** est un **clone local** de léditeur **Lapce** (socle applicatif), présent **dans larborescence du monorepo** sur disque ; il est **exclu de lindex Git du parent** par volumétrie (voir racine `.gitignore`). Mise à jour : procédure dans [core-ide.md](./core-ide.md).
- `ia_dev` est un **répertoire versionné** dans ce monorepo (évolution historique depuis le dépôt forge [4nk/ia_dev](https://git.4nkweb.com/4nk/ia_dev.git)) ; intégration et journaux : [ia_dev-module.md](./ia_dev-module.md), [repo/ia-dev-smart-ide-integration.md](./repo/ia-dev-smart-ide-integration.md), [repo/logs-directory.md](./repo/logs-directory.md). Un service HTTP **`ia-dev-gateway`** ([features/ia-dev-service.md](./features/ia-dev-service.md)) exposera le registre et les exécutions agents.
- `ia_dev` est un **répertoire versionné** dans ce monorepo (évolution historique depuis le dépôt forge [4nk/ia_dev](https://git.4nkweb.com/4nk/ia_dev.git)) sous **`services/ia_dev/`** ; intégration et journaux : [ia_dev-module.md](./ia_dev-module.md), [repo/ia-dev-smart-ide-integration.md](./repo/ia-dev-smart-ide-integration.md), [repo/logs-directory.md](./repo/logs-directory.md). Un service HTTP **`ia-dev-gateway`** ([features/ia-dev-service.md](./features/ia-dev-service.md)) expose le registre et les exécutions agents.
- **Orchestrateur** HTTP : [features/orchestrator-api.md](./features/orchestrator-api.md) — serveur stub sous `services/smart-ide-orchestrator/` ; routage intentions → Ollama, AnythingLLM, micro-services, `ia-dev-gateway` (forward HTTP à compléter).
## Cartographie des ressources (arborescence)
@ -41,7 +41,7 @@ Conséquences :
| `services/local-office/` | **API REST** Office (upload, commandes docx, stockage SQLite + fichiers) ; complément programmatique à ONLYOFFICE |
| `services/docv/` | **Contrat dintégration** docv (hors monorepo) ; données projet sous `../projects/<id>/data/` ; pas de code applicatif docv ici — [features/docv-service-integration.md](./features/docv-service-integration.md) |
| `projects/<id>/` (racine monorepo) | **Confs seules** pour `ia_dev` (`conf.json`) — **pas** les clones Git ; clones typiquement sous `../projects/` ou autre racine ; voir [repo/projects-directory.md](./repo/projects-directory.md) |
| `ia_dev/` | Agents, déploiements — exécution sous policy ; `ia_dev/projects/<id>` peut pointer vers `../../projects/<id>` (lien) ; voir [ia_dev-module.md](./ia_dev-module.md) |
| `services/ia_dev/` | Agents, déploiements — exécution sous policy ; `services/ia_dev/projects/<id>` peut pointer vers `../../projects/<id>` (lien) ; voir [ia_dev-module.md](./ia_dev-module.md) |
| `services/ia-dev-gateway/` | Gateway HTTP (stub runner) : registre agents `.md`, runs, SSE — [features/ia-dev-service.md](./features/ia-dev-service.md) |
| `services/smart-ide-orchestrator/` | Routage intentions (stub forward) — [features/orchestrator-api.md](./features/orchestrator-api.md) |
| `services/smart-ide-tools-bridge/` | API IDE : registre des services + Carbonyl / PageIndex / Chandra — [repo/service-smart-ide-tools-bridge.md](./repo/service-smart-ide-tools-bridge.md) |
@ -56,7 +56,7 @@ Chaque environnement possède ses **URLs**, **secrets** et **politiques** (Anyth
## Module `ia_dev` dans ce dépôt
Le répertoire **`./ia_dev`** fait partie du dépôt **smart_ide** (référence historique : [4nk/ia_dev](https://git.4nkweb.com/4nk/ia_dev.git) sur la forge). Sur le serveur SSH, l**agent gateway** et les outils peuvent pointer vers ce chemin comme racine dexécution des agents (scripts invoqués depuis la racine `ia_dev`). Voir [ia_dev-module.md](./ia_dev-module.md) et [repo/ia-dev-smart-ide-integration.md](./repo/ia-dev-smart-ide-integration.md).
Le répertoire **`./services/ia_dev`** fait partie du dépôt **smart_ide** (référence historique : [4nk/ia_dev](https://git.4nkweb.com/4nk/ia_dev.git) sur la forge). Sur le serveur SSH, l**agent gateway** et les outils peuvent pointer vers `IA_DEV_ROOT` (résolution par défaut : `./ia_dev` puis `./services/ia_dev`) comme racine dexécution des agents (scripts invoqués depuis la racine `ia_dev`). Voir [ia_dev-module.md](./ia_dev-module.md) et [repo/ia-dev-smart-ide-integration.md](./repo/ia-dev-smart-ide-integration.md).
## Répartition physique (première cible)

1
ia_dev

@ -1 +0,0 @@
Subproject commit b4ce81858cf4ba10b5a5ac16ea4ebc6f94e85a5d

44
patches/lapce/README.md Normal file
View File

@ -0,0 +1,44 @@
# Lapce patches (Smart IDE)
This folder versions the **Smart IDE** modifications applied to **Lapce**.
Why this exists:
- The Lapce checkout lives in `core_ide/` (and is ignored by the parent `smart_ide` git repository).
- We still want a **reviewable**, **replayable** history of the core editor changes.
## Files
- `series`: ordered list of patch filenames to apply (one per line, `#` comments allowed).
- `*.patch`: `git format-patch` output generated from `core_ide/`.
## Workflow
### Apply patches to `core_ide/`
From the `smart_ide` repo root:
```bash
./scripts/core-ide-apply-patches.sh
```
### Export patches from `core_ide/`
1. Make commits inside `core_ide/` (in a dedicated branch, e.g. `smart-ide`).
2. Export the patch series:
```bash
./scripts/core-ide-export-patches.sh
```
This regenerates `patches/lapce/*.patch` and rewrites `patches/lapce/series`.
## Remotes
Recommended convention inside `core_ide/`:
- `upstream`: official Lapce (`https://github.com/lapce/lapce.git`)
- `origin`: internal fork (team forge)
Use `./scripts/ensure-core-ide.sh --fork-url <...>` to set this up.

3
patches/lapce/series Normal file
View File

@ -0,0 +1,3 @@
# List Lapce patch files (one per line).
# This file is consumed by: ./scripts/core-ide-apply-patches.sh

View File

@ -4,7 +4,7 @@
"cron": {
"git_pull": true
},
"project_path": "builazoo",
"project_path": "../builazoo",
"build_dirs": [],
"deploy": {},
"version": {

View File

@ -28,17 +28,54 @@ const git = (repoRoot, args) => {
};
const parseArgs = () => {
const out = { repoRoot: process.cwd() };
const out = { repoRoot: process.cwd(), uploadAll: false, uploadPrefix: "" };
const argv = process.argv.slice(2);
for (let i = 0; i < argv.length; i += 1) {
if (argv[i] === "--repo-root" && argv[i + 1]) {
out.repoRoot = path.resolve(argv[i + 1]);
i += 1;
continue;
}
if (argv[i] === "--upload-all") {
out.uploadAll = true;
continue;
}
if (argv[i] === "--upload-prefix" && argv[i + 1]) {
out.uploadPrefix = String(argv[i + 1] ?? "").trim();
i += 1;
continue;
}
}
return out;
};
const walkFiles = async (dir) => {
const out = [];
const scan = async (d) => {
const entries = await fsPromises.readdir(d, { withFileTypes: true });
for (const e of entries) {
const p = path.join(d, e.name);
if (e.isSymbolicLink()) {
continue;
}
if (e.isDirectory()) {
await scan(p);
continue;
}
if (e.isFile()) {
out.push(p);
}
}
};
await scan(dir);
return out;
};
const toPosixRel = (root, abs) => {
const rel = path.relative(root, abs);
return rel.split(path.sep).join("/");
};
const loadWorkspaceSlug = (repoRoot) => {
const env = process.env.ANYTHINGLLM_WORKSPACE_SLUG?.trim();
if (env) {
@ -53,6 +90,63 @@ const loadWorkspaceSlug = (repoRoot) => {
} catch {
/* missing */
}
// smart_ide integration: resolve slug from projects/<id>/conf.json when available.
// This avoids having to write per-repo config files into the target clones.
try {
const smartIdeRoot = path.resolve(__dirname, "..", "..");
const projectsDir = path.join(smartIdeRoot, "projects");
if (!fs.existsSync(projectsDir)) {
return "";
}
const repoReal = fs.realpathSync(repoRoot);
const envNameRaw = process.env.SMART_IDE_ENV?.trim() ?? "";
const envName = envNameRaw === "test" || envNameRaw === "pprod" || envNameRaw === "prod" ? envNameRaw : "test";
for (const ent of fs.readdirSync(projectsDir, { withFileTypes: true })) {
if (!ent.isDirectory()) {
continue;
}
const confPath = path.join(projectsDir, ent.name, "conf.json");
if (!fs.existsSync(confPath)) {
continue;
}
let conf;
try {
conf = readJson(confPath);
} catch {
continue;
}
const projectPath = typeof conf?.project_path === "string" ? conf.project_path.trim() : "";
if (!projectPath) {
continue;
}
const absProjectPath = path.isAbsolute(projectPath)
? projectPath
: path.resolve(smartIdeRoot, projectPath);
let projectReal;
try {
projectReal = fs.realpathSync(absProjectPath);
} catch {
continue;
}
if (projectReal !== repoReal) {
continue;
}
const slugCfg = conf?.smart_ide?.anythingllm_workspace_slug;
if (typeof slugCfg === "string" && slugCfg.trim().length > 0) {
return slugCfg.trim();
}
if (slugCfg && typeof slugCfg === "object") {
const slug = slugCfg?.[envName];
if (typeof slug === "string" && slug.trim().length > 0) {
return slug.trim();
}
}
}
} catch {
// ignore and fall back to empty (explicit skip handled by caller)
}
return "";
};
@ -62,6 +156,28 @@ const normalizeApiKey = (raw) => {
return m ? t.slice(m[0].length).trim() : t;
};
const readPositiveIntEnv = (name, fallback) => {
const raw = process.env[name];
if (!raw || raw.trim().length === 0) {
return fallback;
}
const s = raw.trim();
if (!/^\d+$/.test(s)) {
console.error(
`anythingllm-pull-sync: invalid ${name}=${JSON.stringify(raw)}; using default ${fallback}`,
);
return fallback;
}
const n = Number(s);
if (!Number.isFinite(n) || n <= 0) {
console.error(
`anythingllm-pull-sync: invalid ${name}=${JSON.stringify(raw)}; using default ${fallback}`,
);
return fallback;
}
return n;
};
const uploadOne = async (baseUrl, apiKey, slug, absPath, uploadName) => {
const root = baseUrl.replace(/\/+$/, "");
const buf = await fsPromises.readFile(absPath);
@ -86,11 +202,11 @@ const uploadOne = async (baseUrl, apiKey, slug, absPath, uploadName) => {
};
const main = async () => {
const { repoRoot } = parseArgs();
const { repoRoot, uploadAll, uploadPrefix } = parseArgs();
const baseUrl = process.env.ANYTHINGLLM_BASE_URL?.trim() ?? "";
const apiKeyRaw = process.env.ANYTHINGLLM_API_KEY?.trim() ?? "";
const maxBytes = Number(process.env.ANYTHINGLLM_SYNC_MAX_FILE_BYTES ?? 5242880);
const maxFiles = Number(process.env.ANYTHINGLLM_SYNC_MAX_FILES ?? 200);
const maxBytes = readPositiveIntEnv("ANYTHINGLLM_SYNC_MAX_FILE_BYTES", 5_242_880);
const maxFiles = readPositiveIntEnv("ANYTHINGLLM_SYNC_MAX_FILES", 200);
if (!baseUrl || !apiKeyRaw) {
console.error(
@ -107,6 +223,76 @@ const main = async () => {
process.exit(0);
}
if (uploadAll === true) {
const ignorePath = path.join(repoRoot, ".4nkaiignore");
let userRules = "";
try {
userRules = await fsPromises.readFile(ignorePath, "utf8");
} catch {
userRules = "";
}
const ig = ignore();
ig.add(ALWAYS_IGNORE);
ig.add(userRules);
let uploaded = 0;
let skipped = 0;
const errors = [];
const absFiles = await walkFiles(repoRoot);
for (const abs of absFiles) {
const rel = toPosixRel(repoRoot, abs);
if (rel.length === 0 || rel.startsWith("..")) {
skipped += 1;
continue;
}
if (ig.ignores(rel)) {
skipped += 1;
continue;
}
let st;
try {
st = await fsPromises.stat(abs);
} catch {
skipped += 1;
continue;
}
if (!st.isFile()) {
skipped += 1;
continue;
}
if (st.size > maxBytes) {
skipped += 1;
continue;
}
if (uploaded >= maxFiles) {
console.error("anythingllm-pull-sync: cap reached (ANYTHINGLLM_SYNC_MAX_FILES).");
break;
}
const relPosix = rel.split(path.sep).join("/");
const baseName = relPosix.split("/").join("__");
const uploadName =
uploadPrefix && uploadPrefix.length > 0 ? `${uploadPrefix}__${baseName}` : baseName;
try {
await uploadOne(baseUrl, apiKey, slug, abs, uploadName);
uploaded += 1;
} catch (e) {
errors.push(`${relPosix}: ${e instanceof Error ? e.message : String(e)}`);
}
}
console.error(
`anythingllm-pull-sync: mode=upload-all uploaded=${uploaded} skipped=${skipped} errors=${errors.length}`,
);
for (const line of errors.slice(0, 20)) {
console.error(line);
}
if (errors.length > 20) {
console.error(`${errors.length - 20} more`);
}
process.exit(errors.length > 0 ? 1 : 0);
}
try {
git(repoRoot, ["rev-parse", "-q", "--verify", "ORIG_HEAD"]);
} catch {
@ -125,7 +311,10 @@ const main = async () => {
]);
names = out.length > 0 ? out.split("\n").filter(Boolean) : [];
} catch (e) {
console.error("anythingllm-pull-sync: git diff failed — skip.", e.message);
console.error(
"anythingllm-pull-sync: git diff failed — skip.",
e instanceof Error ? e.message : String(e),
);
process.exit(0);
}
@ -197,7 +386,7 @@ const main = async () => {
if (errors.length > 20) {
console.error(`${errors.length - 20} more`);
}
process.exit(0);
process.exit(errors.length > 0 ? 1 : 0);
};
main().catch((e) => {

View File

@ -0,0 +1,56 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CORE_IDE_DIR="${ROOT}/core_ide"
PATCH_DIR="${ROOT}/patches/lapce"
SERIES_FILE="${PATCH_DIR}/series"
if [[ ! -d "${CORE_IDE_DIR}/.git" ]]; then
echo "Missing core_ide git checkout: ${CORE_IDE_DIR}" >&2
echo "Run: ./scripts/ensure-core-ide.sh" >&2
exit 1
fi
if [[ ! -f "${SERIES_FILE}" ]]; then
echo "Missing patch series file: ${SERIES_FILE}" >&2
exit 1
fi
if [[ -d "${CORE_IDE_DIR}/.git/rebase-apply" ]] || [[ -d "${CORE_IDE_DIR}/.git/rebase-merge" ]]; then
echo "core_ide has an in-progress rebase/am. Resolve it first." >&2
exit 1
fi
if [[ -n "$(git -C "${CORE_IDE_DIR}" status --porcelain)" ]]; then
echo "core_ide working tree is not clean. Commit/stash changes before applying patches." >&2
exit 1
fi
mapfile -t PATCHES < <(
sed -e 's/[[:space:]]\+$//' "${SERIES_FILE}" \
| awk 'NF && $1 !~ /^#/' \
| cat
)
if [[ ${#PATCHES[@]} -eq 0 ]]; then
echo "No patches listed in ${SERIES_FILE}. Nothing to apply."
exit 0
fi
for rel in "${PATCHES[@]}"; do
patch_path="${PATCH_DIR}/${rel}"
if [[ ! -f "${patch_path}" ]]; then
echo "Patch file not found: ${patch_path}" >&2
exit 1
fi
echo "Applying: ${rel}"
if ! git -C "${CORE_IDE_DIR}" am --3way "${patch_path}"; then
echo "Patch failed: ${rel}" >&2
echo "To abort: (cd core_ide && git am --abort)" >&2
exit 1
fi
done
echo "OK: applied ${#PATCHES[@]} patch(es) to core_ide."

View File

@ -0,0 +1,114 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CORE_IDE_DIR="${ROOT}/core_ide"
PATCH_DIR="${ROOT}/patches/lapce"
SERIES_FILE="${PATCH_DIR}/series"
BASE_REF=""
usage() {
cat <<'EOF'
Usage:
./scripts/core-ide-export-patches.sh [--base <git-ref>]
Exports the commits in core_ide (BASE..HEAD) as patch files into:
patches/lapce/*.patch
and rewrites:
patches/lapce/series
If --base is not provided, the script tries (first match):
upstream/master, upstream/main, origin/master, origin/main
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
--base)
BASE_REF="${2:-}"
shift 2
;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 2
;;
esac
done
if [[ ! -d "${CORE_IDE_DIR}/.git" ]]; then
echo "Missing core_ide git checkout: ${CORE_IDE_DIR}" >&2
exit 1
fi
mkdir -p "${PATCH_DIR}"
if [[ ! -f "${SERIES_FILE}" ]]; then
echo "Missing series file: ${SERIES_FILE}" >&2
exit 1
fi
if [[ -n "$(git -C "${CORE_IDE_DIR}" status --porcelain)" ]]; then
echo "core_ide working tree is not clean. Commit changes before exporting patches." >&2
exit 1
fi
ref_exists() {
git -C "${CORE_IDE_DIR}" show-ref --verify --quiet "refs/remotes/$1" \
|| git -C "${CORE_IDE_DIR}" show-ref --verify --quiet "refs/heads/$1" \
|| git -C "${CORE_IDE_DIR}" rev-parse --verify --quiet "$1" >/dev/null 2>&1
}
if [[ -z "${BASE_REF}" ]]; then
for candidate in "upstream/master" "upstream/main" "origin/master" "origin/main"; do
if ref_exists "${candidate}"; then
BASE_REF="${candidate}"
break
fi
done
fi
if [[ -z "${BASE_REF}" ]]; then
echo "Could not auto-detect a base ref. Provide --base <ref>." >&2
exit 1
fi
HEAD_SHA="$(git -C "${CORE_IDE_DIR}" rev-parse HEAD)"
BASE_SHA="$(git -C "${CORE_IDE_DIR}" rev-parse "${BASE_REF}")"
if [[ "${HEAD_SHA}" == "${BASE_SHA}" ]]; then
echo "No commits to export (HEAD equals base ${BASE_REF})."
rm -f "${PATCH_DIR}"/*.patch
printf "%s\n" \
"# List Lapce patch files (one per line)." \
"# This file is consumed by: ./scripts/core-ide-apply-patches.sh" \
"" \
>"${SERIES_FILE}"
exit 0
fi
rm -f "${PATCH_DIR}"/*.patch
git -C "${CORE_IDE_DIR}" format-patch \
--output-directory "${PATCH_DIR}" \
--no-stat \
--no-signature \
"${BASE_REF}..HEAD"
(
cd "${PATCH_DIR}"
{
echo "# List Lapce patch files (one per line)."
echo "# This file is consumed by: ./scripts/core-ide-apply-patches.sh"
echo
ls -1 *.patch 2>/dev/null | sort
} >"${SERIES_FILE}"
)
echo "OK: exported patches to ${PATCH_DIR} (base=${BASE_REF})."

84
scripts/ensure-core-ide.sh Executable file
View File

@ -0,0 +1,84 @@
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage:
./scripts/ensure-core-ide.sh [--fork-url <git_url>] [--upstream-url <git_url>]
What it does:
- Ensures the Lapce checkout exists at ./core_ide (ignored by the parent repo).
- Optionally configures remotes for a fork workflow:
- origin = fork (if --fork-url is provided)
- upstream = official Lapce upstream (default: https://github.com/lapce/lapce.git)
Notes:
- This script does not write any secrets.
- If you cloned with --depth 1 and need full history later:
(cd core_ide && git fetch --unshallow)
EOF
}
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CORE_IDE_DIR="${ROOT}/core_ide"
FORK_URL=""
UPSTREAM_URL="https://github.com/lapce/lapce.git"
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
--fork-url)
FORK_URL="${2:-}"
shift 2
;;
--upstream-url)
UPSTREAM_URL="${2:-}"
shift 2
;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 2
;;
esac
done
if [[ -d "${CORE_IDE_DIR}/.git" ]]; then
echo "core_ide already exists: ${CORE_IDE_DIR}"
else
echo "core_ide missing; cloning..."
mkdir -p "${ROOT}"
if [[ -n "${FORK_URL}" ]]; then
git clone --depth 1 "${FORK_URL}" "${CORE_IDE_DIR}"
else
git clone --depth 1 "${UPSTREAM_URL}" "${CORE_IDE_DIR}"
fi
fi
if [[ ! -f "${CORE_IDE_DIR}/Cargo.toml" ]]; then
echo "core_ide does not look like a Lapce checkout (missing Cargo.toml): ${CORE_IDE_DIR}" >&2
exit 1
fi
(
cd "${CORE_IDE_DIR}"
# Ensure upstream remote exists (official Lapce).
if ! git remote get-url upstream >/dev/null 2>&1; then
git remote add upstream "${UPSTREAM_URL}"
fi
if [[ -n "${FORK_URL}" ]]; then
git remote set-url origin "${FORK_URL}"
fi
echo "Remotes:"
git remote -v
)
echo "OK"

View File

@ -11,8 +11,21 @@ if [[ ! -f "${CONF}" ]]; then
exit 1
fi
LINK_PARENT="${ROOT}/ia_dev/projects"
IA_DEV_DIR=""
if [[ -d "${ROOT}/ia_dev" ]]; then
IA_DEV_DIR="${ROOT}/ia_dev"
elif [[ -d "${ROOT}/services/ia_dev" ]]; then
IA_DEV_DIR="${ROOT}/services/ia_dev"
else
echo "Missing ia_dev directory: expected '${ROOT}/ia_dev' or '${ROOT}/services/ia_dev'" >&2
exit 1
fi
LINK_PARENT="${IA_DEV_DIR}/projects"
TARGET="../../projects/${PROJECT_ID}"
if [[ "${IA_DEV_DIR}" == "${ROOT}/services/ia_dev" ]]; then
TARGET="../../../projects/${PROJECT_ID}"
fi
LINK_NAME="${LINK_PARENT}/${PROJECT_ID}"
mkdir -p "${LINK_PARENT}"
if [[ -e "${LINK_NAME}" && ! -L "${LINK_NAME}" ]]; then

View File

@ -1,33 +1,86 @@
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <path-to-git-repo> [<path-to-smart_ide>]" >&2
exit 1
usage() {
cat <<'EOF' >&2
Usage:
install hook for one repo:
./scripts/install-anythingllm-post-merge-hook.sh <path-to-git-repo> [<path-to-smart_ide>]
install hook for configured project clones:
./scripts/install-anythingllm-post-merge-hook.sh --all [--smart-ide-root <path>]
./scripts/install-anythingllm-post-merge-hook.sh --project <id> [--smart-ide-root <path>]
Notes:
- Project clones are resolved from smart_ide `projects/<id>/conf.json` -> `project_path`.
- The hook sources `${HOME}/.config/4nk/anythingllm-sync.env` if present.
EOF
}
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SMART_IDE_ROOT=""
repo_paths=()
mode="single"
filter_project_id=""
if [[ $# -ge 1 && "${1:-}" != --* ]]; then
# Backward-compatible mode: <repo> [<smart_ide_root>]
repo_paths+=( "$1" )
SMART_IDE_ROOT="${2:-}"
else
while [[ $# -gt 0 ]]; do
case "$1" in
--smart-ide-root)
SMART_IDE_ROOT="${2:-}"
shift 2
;;
--all)
mode="all"
shift 1
;;
--project)
filter_project_id="${2:-}"
[[ -n "$filter_project_id" ]] || { echo "Missing value for --project" >&2; usage; exit 2; }
mode="project"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown arg: $1" >&2
usage
exit 2
;;
esac
done
fi
REPO=$(cd "$1" && pwd)
SMART_IDE_ROOT=${2:-}
if [[ -z "$SMART_IDE_ROOT" ]]; then
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
SMART_IDE_ROOT=$(cd "$SCRIPT_DIR/.." && pwd)
SMART_IDE_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
else
SMART_IDE_ROOT="$(cd "$SMART_IDE_ROOT" && pwd)"
fi
SYNC_DIR="$SMART_IDE_ROOT/scripts/anythingllm-pull-sync"
HOOK="$REPO/.git/hooks/post-merge"
if [[ ! -d "$REPO/.git" ]]; then
echo "Not a git repository: $REPO" >&2
exit 1
fi
if [[ ! -f "$SYNC_DIR/sync.mjs" ]]; then
echo "Missing $SYNC_DIR/sync.mjs" >&2
exit 1
fi
mkdir -p "$(dirname "$HOOK")"
cat >"$HOOK" <<EOF
install_one() {
local repo_path="$1"
local repo
repo="$(cd "$repo_path" && pwd)"
if [[ ! -d "$repo/.git" ]]; then
echo "Not a git repository: $repo" >&2
return 1
fi
local hook="$repo/.git/hooks/post-merge"
mkdir -p "$(dirname "$hook")"
cat >"$hook" <<EOF
#!/usr/bin/env sh
# Installed by install-anythingllm-post-merge-hook.sh — AnythingLLM upload after pull (post-merge)
REPO_ROOT=\$(git rev-parse --show-toplevel)
@ -37,6 +90,74 @@ if [ -f "\${HOME}/.config/4nk/anythingllm-sync.env" ]; then
fi
exec node "$SYNC_DIR/sync.mjs" --repo-root "\$REPO_ROOT"
EOF
chmod +x "$HOOK"
echo "Installed post-merge hook: $HOOK"
chmod +x "$hook"
echo "Installed post-merge hook: $hook"
return 0
}
if [[ "$mode" == "single" ]]; then
if [[ ${#repo_paths[@]} -ne 1 ]]; then
usage
exit 2
fi
install_one "${repo_paths[0]}"
echo "Run: (cd $SYNC_DIR && npm install) if node_modules is missing."
exit 0
fi
command -v jq >/dev/null 2>&1 || {
echo "jq not found; install jq." >&2
exit 1
}
projects_dir="$SMART_IDE_ROOT/projects"
if [[ ! -d "$projects_dir" ]]; then
echo "Missing projects dir: $projects_dir" >&2
exit 1
fi
count_ok=0
count_skip=0
count_err=0
for conf in "$projects_dir"/*/conf.json; do
[[ -f "$conf" ]] || continue
project_id="$(basename "$(dirname "$conf")")"
if [[ "$mode" == "project" && "$project_id" != "$filter_project_id" ]]; then
continue
fi
if [[ "$project_id" == "example" ]]; then
echo "skip $project_id: template project"
count_skip=$((count_skip + 1))
continue
fi
if ! project_path="$(jq -r '.project_path // empty' "$conf")"; then
echo "err $project_id: failed to read project_path from $conf" >&2
count_err=$((count_err + 1))
continue
fi
if [[ -z "$project_path" || "$project_path" == "null" ]]; then
echo "skip $project_id: empty project_path"
count_skip=$((count_skip + 1))
continue
fi
if [[ "$project_path" != /* ]]; then
project_path="$(cd "$SMART_IDE_ROOT" && realpath -m "$project_path" 2>/dev/null || echo "$SMART_IDE_ROOT/$project_path")"
fi
if [[ ! -d "$project_path" ]]; then
echo "skip $project_id: not a directory: $project_path"
count_skip=$((count_skip + 1))
continue
fi
if install_one "$project_path"; then
count_ok=$((count_ok + 1))
else
count_err=$((count_err + 1))
fi
done
echo "Done: ok=$count_ok skip=$count_skip err=$count_err"
echo "Run: (cd $SYNC_DIR && npm install) if node_modules is missing."
if [[ "$count_err" -gt 0 ]]; then
exit 1
fi

318
scripts/remote-data-ssh-sync.sh Executable file
View File

@ -0,0 +1,318 @@
#!/usr/bin/env bash
# Pull deployed data directories over SSH into a local mirror, then optionally ingest into AnythingLLM.
#
# Source of truth:
# projects/<id>/conf.json -> smart_ide.remote_data_access.environments.<env>
#
# This script never writes to remote databases. It only performs SSH/rsync reads.
set -euo pipefail
usage() {
cat <<'EOF'
Usage:
./scripts/remote-data-ssh-sync.sh [--project <id>] [--env <test|pprod|prod>]
[--mirror-root <abs_path>]
[--roles <comma_separated_roles>]
[--no-anythingllm]
[--max-files <n>] [--max-bytes <n>]
[--dry-run]
Project/env resolution (first match):
- --project / --env
- SMART_IDE_PROJECT_ID / SMART_IDE_ENV
- projects/active-project.json (local, gitignored)
Mirror root:
- SMART_IDE_REMOTE_DATA_MIRROR_ROOT, else <smart_ide_root>/.data/remote-data
AnythingLLM ingestion:
- enabled by default (skip if AnythingLLM config or workspace slug is missing)
- reads workspace slug from projects/<id>/conf.json -> smart_ide.anythingllm_workspace_slug[env]
- reads ANYTHINGLLM_BASE_URL / ANYTHINGLLM_API_KEY from ~/.config/4nk/anythingllm-sync.env if present
- uses scripts/anythingllm-pull-sync/sync.mjs in --upload-all mode
Notes:
- Requires: jq, ssh, rsync, node (>=20).
- Output is not filtered; rsync output remains visible.
EOF
}
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
ACTIVE_PROJECT_FILE="${ROOT}/projects/active-project.json"
PROJECT_ID="${SMART_IDE_PROJECT_ID:-}"
ENV_NAME="${SMART_IDE_ENV:-}"
MIRROR_ROOT="${SMART_IDE_REMOTE_DATA_MIRROR_ROOT:-${ROOT}/.data/remote-data}"
INGEST_ANYTHINGLLM="true"
ROLES_CSV=""
DRY_RUN="false"
MAX_FILES="${ANYTHINGLLM_SYNC_MAX_FILES:-200}"
MAX_BYTES="${ANYTHINGLLM_SYNC_MAX_FILE_BYTES:-5242880}"
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
--project)
PROJECT_ID="${2:-}"
shift 2
;;
--env)
ENV_NAME="${2:-}"
shift 2
;;
--mirror-root)
MIRROR_ROOT="${2:-}"
shift 2
;;
--roles)
ROLES_CSV="${2:-}"
shift 2
;;
--no-anythingllm)
INGEST_ANYTHINGLLM="false"
shift 1
;;
--max-files)
MAX_FILES="${2:-}"
shift 2
;;
--max-bytes)
MAX_BYTES="${2:-}"
shift 2
;;
--dry-run)
DRY_RUN="true"
shift 1
;;
*)
echo "[remote-data-ssh-sync][ERROR] Unknown arg: $1" >&2
usage >&2
exit 2
;;
esac
done
command -v jq >/dev/null 2>&1 || { echo "[remote-data-ssh-sync][ERROR] Missing dependency: jq" >&2; exit 1; }
command -v ssh >/dev/null 2>&1 || { echo "[remote-data-ssh-sync][ERROR] Missing dependency: ssh" >&2; exit 1; }
command -v rsync >/dev/null 2>&1 || { echo "[remote-data-ssh-sync][ERROR] Missing dependency: rsync" >&2; exit 1; }
command -v node >/dev/null 2>&1 || { echo "[remote-data-ssh-sync][ERROR] Missing dependency: node" >&2; exit 1; }
if [[ -z "${PROJECT_ID}" && -f "${ACTIVE_PROJECT_FILE}" ]]; then
PROJECT_ID="$(jq -r '.id // empty' "${ACTIVE_PROJECT_FILE}")"
fi
if [[ -z "${ENV_NAME}" && -f "${ACTIVE_PROJECT_FILE}" ]]; then
ENV_NAME="$(jq -r '.default_env // empty' "${ACTIVE_PROJECT_FILE}")"
fi
if [[ -z "${PROJECT_ID}" ]]; then
echo "[remote-data-ssh-sync][ERROR] Missing project id. Provide --project <id> or create projects/active-project.json" >&2
exit 1
fi
if [[ -z "${ENV_NAME}" ]]; then
ENV_NAME="test"
fi
case "${ENV_NAME}" in
test|pprod|prod) ;;
*)
echo "[remote-data-ssh-sync][ERROR] Invalid --env: ${ENV_NAME} (expected test|pprod|prod)" >&2
exit 1
;;
esac
CONF_FILE="${ROOT}/projects/${PROJECT_ID}/conf.json"
if [[ ! -f "${CONF_FILE}" ]]; then
echo "[remote-data-ssh-sync][ERROR] Missing project conf: ${CONF_FILE}" >&2
exit 1
fi
SSH_HOST_ALIAS="$(
jq -r ".smart_ide.remote_data_access.environments.${ENV_NAME}.ssh_host_alias // empty" "${CONF_FILE}"
)"
if [[ -z "${SSH_HOST_ALIAS}" || "${SSH_HOST_ALIAS}" == "null" ]]; then
echo "[remote-data-ssh-sync][ERROR] Missing ssh_host_alias for ${PROJECT_ID}/${ENV_NAME} in ${CONF_FILE}" >&2
exit 1
fi
mapfile -t ITEMS < <(jq -c ".smart_ide.remote_data_access.environments.${ENV_NAME}.remote_data_directories[]? // empty" "${CONF_FILE}")
if [[ ${#ITEMS[@]} -eq 0 ]]; then
echo "[remote-data-ssh-sync] No remote_data_directories configured for ${PROJECT_ID}/${ENV_NAME} (nothing to do)."
exit 0
fi
MIRROR_ROOT_ABS="${MIRROR_ROOT}"
if [[ "${MIRROR_ROOT_ABS}" != /* ]]; then
MIRROR_ROOT_ABS="$(cd "${ROOT}" && realpath -m "${MIRROR_ROOT_ABS}" 2>/dev/null || echo "${ROOT}/${MIRROR_ROOT_ABS}")"
fi
base_dir="${MIRROR_ROOT_ABS}/${PROJECT_ID}/${ENV_NAME}"
mkdir -p "${base_dir}"
tmp_items="$(mktemp -t remote-data-items.XXXXXX)"
cleanup() {
rm -f "${tmp_items}"
}
trap cleanup EXIT
echo "[remote-data-ssh-sync] projectId=${PROJECT_ID}"
echo "[remote-data-ssh-sync] env=${ENV_NAME}"
echo "[remote-data-ssh-sync] sshHostAlias=${SSH_HOST_ALIAS}"
echo "[remote-data-ssh-sync] mirrorRoot=${MIRROR_ROOT_ABS}"
echo "[remote-data-ssh-sync] items=${#ITEMS[@]}"
echo
should_ingest_role() {
local role="$1"
if [[ -z "${ROLES_CSV}" ]]; then
return 0
fi
local IFS=,
read -r -a allowed <<<"${ROLES_CSV}"
for r in "${allowed[@]}"; do
if [[ "$(echo "$r" | sed 's/[[:space:]]//g')" == "$role" ]]; then
return 0
fi
done
return 1
}
for item in "${ITEMS[@]}"; do
role="$(echo "$item" | jq -r '.role // empty')"
remote_path="$(echo "$item" | jq -r '.path_on_server // empty')"
if [[ -z "$role" || -z "$remote_path" || "$role" == "null" || "$remote_path" == "null" ]]; then
echo "[remote-data-ssh-sync][WARN] Skip invalid item: ${item}" >&2
continue
fi
if [[ "${remote_path}" != /* ]]; then
echo "[remote-data-ssh-sync][WARN] Skip non-absolute path_on_server for role '${role}': ${remote_path}" >&2
continue
fi
dest="${base_dir}/${role}"
echo "[remote-data-ssh-sync] rsync role=${role}"
echo " from: ${SSH_HOST_ALIAS}:${remote_path}"
echo " to : ${dest}"
# Trailing slash to mirror directory contents into dest/
src="${SSH_HOST_ALIAS}:${remote_path%/}/"
synced_json="false"
if [[ "${DRY_RUN}" == "true" ]]; then
echo " dry-run: rsync -a --delete -e \"ssh -o BatchMode=yes\" \"${src}\" \"${dest}/\""
else
mkdir -p "${dest}"
rsync -a --delete -e "ssh -o BatchMode=yes" "${src}" "${dest}/"
synced_json="true"
fi
echo "$item" | jq -c --arg dest "$dest" --argjson synced "${synced_json}" '{ role: (.role // ""), path_on_server: (.path_on_server // ""), dest: $dest, synced: $synced }' >>"${tmp_items}"
echo
done
manifest="${base_dir}/manifest.json"
started_at="$(date -Iseconds)"
if [[ -s "${tmp_items}" ]]; then
jq -s \
--arg projectId "${PROJECT_ID}" \
--arg env "${ENV_NAME}" \
--arg sshHostAlias "${SSH_HOST_ALIAS}" \
--arg startedAt "${started_at}" \
--argjson dryRun "$( [[ "${DRY_RUN}" == "true" ]] && echo true || echo false )" \
'{ projectId: $projectId, env: $env, sshHostAlias: $sshHostAlias, startedAt: $startedAt, dryRun: $dryRun, items: . }' \
"${tmp_items}" >"${manifest}"
else
jq -n \
--arg projectId "${PROJECT_ID}" \
--arg env "${ENV_NAME}" \
--arg sshHostAlias "${SSH_HOST_ALIAS}" \
--arg startedAt "${started_at}" \
--argjson dryRun "$( [[ "${DRY_RUN}" == "true" ]] && echo true || echo false )" \
'{ projectId: $projectId, env: $env, sshHostAlias: $sshHostAlias, startedAt: $startedAt, dryRun: $dryRun, items: [] }' \
>"${manifest}"
fi
echo "[remote-data-ssh-sync] manifest=${manifest}"
if [[ "${INGEST_ANYTHINGLLM}" != "true" ]]; then
echo "[remote-data-ssh-sync] AnythingLLM ingestion disabled (--no-anythingllm)."
exit 0
fi
workspace_slug="$(
jq -r --arg env "${ENV_NAME}" '
.smart_ide.anythingllm_workspace_slug as $s
| if ($s|type) == "string" then $s
elif ($s|type) == "object" then ($s[$env] // empty)
else empty end
' "${CONF_FILE}"
)"
workspace_slug="$(echo "${workspace_slug}" | sed 's/[[:space:]]//g')"
if [[ -z "${workspace_slug}" || "${workspace_slug}" == "null" ]]; then
echo "[remote-data-ssh-sync] AnythingLLM: missing smart_ide.anythingllm_workspace_slug for ${PROJECT_ID}/${ENV_NAME} in ${CONF_FILE} — skip."
exit 0
fi
# Optional host-level AnythingLLM env file (same convention as the post-merge hook).
if [[ -f "${HOME}/.config/4nk/anythingllm-sync.env" ]]; then
set -a
# shellcheck source=/dev/null
source "${HOME}/.config/4nk/anythingllm-sync.env"
set +a
fi
if [[ -z "${ANYTHINGLLM_BASE_URL:-}" || -z "${ANYTHINGLLM_API_KEY:-}" ]]; then
echo "[remote-data-ssh-sync] AnythingLLM: missing ANYTHINGLLM_BASE_URL or ANYTHINGLLM_API_KEY — skip."
exit 0
fi
echo
echo "[remote-data-ssh-sync] AnythingLLM ingest workspaceSlug=${workspace_slug}"
echo "[remote-data-ssh-sync] limits: maxFiles=${MAX_FILES} maxBytes=${MAX_BYTES}"
sync_script="${ROOT}/scripts/anythingllm-pull-sync/sync.mjs"
if [[ ! -f "${sync_script}" ]]; then
echo "[remote-data-ssh-sync][ERROR] Missing ${sync_script}" >&2
exit 1
fi
sanitize() {
echo "$1" | sed 's/[^A-Za-z0-9._-]/_/g'
}
ingest_ok=0
ingest_err=0
for item in "${ITEMS[@]}"; do
role="$(echo "$item" | jq -r '.role // empty')"
[[ -n "$role" && "$role" != "null" ]] || continue
if ! should_ingest_role "$role"; then
echo "[remote-data-ssh-sync] AnythingLLM: skip role=${role} (not in --roles)"
continue
fi
dest="${base_dir}/${role}"
if [[ ! -d "${dest}" ]]; then
echo "[remote-data-ssh-sync] AnythingLLM: skip role=${role} (missing dest dir: ${dest})" >&2
continue
fi
prefix="$(sanitize "${PROJECT_ID}")__$(sanitize "${ENV_NAME}")__$(sanitize "${role}")"
echo "[remote-data-ssh-sync] AnythingLLM: upload-all role=${role} (prefix=${prefix})"
if [[ "${DRY_RUN}" == "true" ]]; then
echo " dry-run: ANYTHINGLLM_WORKSPACE_SLUG=... node ${sync_script} --repo-root \"${dest}\" --upload-all --upload-prefix \"${prefix}\""
continue
fi
ANYTHINGLLM_WORKSPACE_SLUG="${workspace_slug}" \
ANYTHINGLLM_SYNC_MAX_FILES="${MAX_FILES}" \
ANYTHINGLLM_SYNC_MAX_FILE_BYTES="${MAX_BYTES}" \
node "${sync_script}" --repo-root "${dest}" --upload-all --upload-prefix "${prefix}" \
&& ingest_ok=$((ingest_ok + 1)) \
|| ingest_err=$((ingest_err + 1))
done
if [[ "${ingest_err}" -gt 0 ]]; then
echo "[remote-data-ssh-sync][ERROR] AnythingLLM ingestion failed for ${ingest_err} role(s); ok=${ingest_ok}" >&2
exit 1
fi
echo "[remote-data-ssh-sync] OK (AnythingLLM ok=${ingest_ok})"

View File

@ -0,0 +1,175 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
ACTIVE_PROJECT_FILE="${ROOT}/projects/active-project.json"
usage() {
cat <<'EOF'
Usage:
./scripts/smart-ide-ssh-tunnel-plan.sh [--project <id>] [--env <test|pprod|prod>] [--mode <minimal|all>] [--json]
Purpose:
Print an SSH tunnel command to reach the Smart IDE services running on a remote host.
Project/env resolution (first match):
- --project / --env
- SMART_IDE_PROJECT_ID / SMART_IDE_ENV
- projects/active-project.json (local, gitignored)
The SSH target is read from:
projects/<id>/conf.json -> smart_ide.remote_data_access.environments.<env>.ssh_host_alias
Notes:
- This prints a command; it does not daemonize anything.
- Bind is limited to 127.0.0.1 on the client.
EOF
}
PROJECT_ID="${SMART_IDE_PROJECT_ID:-}"
ENV_NAME="${SMART_IDE_ENV:-}"
MODE="minimal"
AS_JSON="false"
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
--project)
PROJECT_ID="${2:-}"
shift 2
;;
--env)
ENV_NAME="${2:-}"
shift 2
;;
--mode)
MODE="${2:-}"
shift 2
;;
--json)
AS_JSON="true"
shift 1
;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 2
;;
esac
done
if ! command -v jq >/dev/null 2>&1; then
echo "Missing dependency: jq" >&2
exit 1
fi
if [[ -z "${PROJECT_ID}" ]] && [[ -f "${ACTIVE_PROJECT_FILE}" ]]; then
PROJECT_ID="$(jq -r '.id // empty' "${ACTIVE_PROJECT_FILE}")"
fi
if [[ -z "${ENV_NAME}" ]] && [[ -f "${ACTIVE_PROJECT_FILE}" ]]; then
ENV_NAME="$(jq -r '.default_env // empty' "${ACTIVE_PROJECT_FILE}")"
fi
if [[ -z "${PROJECT_ID}" ]]; then
echo "Missing project id. Provide --project <id> or create projects/active-project.json" >&2
exit 1
fi
if [[ -z "${ENV_NAME}" ]]; then
ENV_NAME="test"
fi
case "${ENV_NAME}" in
test|pprod|prod) ;;
*)
echo "Invalid --env: ${ENV_NAME} (expected test|pprod|prod)" >&2
exit 1
;;
esac
case "${MODE}" in
minimal|all) ;;
*)
echo "Invalid --mode: ${MODE} (expected minimal|all)" >&2
exit 1
;;
esac
CONF_FILE="${ROOT}/projects/${PROJECT_ID}/conf.json"
if [[ ! -f "${CONF_FILE}" ]]; then
echo "Missing project conf: ${CONF_FILE}" >&2
exit 1
fi
SSH_HOST_ALIAS="$(
jq -r ".smart_ide.remote_data_access.environments.${ENV_NAME}.ssh_host_alias // empty" "${CONF_FILE}"
)"
if [[ -z "${SSH_HOST_ALIAS}" ]] || [[ "${SSH_HOST_ALIAS}" == "null" ]]; then
echo "Missing ssh_host_alias for ${PROJECT_ID}/${ENV_NAME} in ${CONF_FILE}" >&2
exit 1
fi
declare -a forwards=()
add_forward() {
local port="$1"
forwards+=("-L" "127.0.0.1:${port}:127.0.0.1:${port}")
}
# Minimal: enough for Lapce to talk to orchestrator + agents + tools jobs via tunnel.
add_forward 37145 # smart-ide-orchestrator
add_forward 37144 # ia-dev-gateway
add_forward 37147 # smart-ide-tools-bridge
if [[ "${MODE}" == "all" ]]; then
add_forward 37149 # smart-ide-global-api (internal; mostly for debugging)
add_forward 37148 # smart-ide-sso-gateway (OIDC front)
add_forward 37146 # anythingllm-devtools
add_forward 37140 # repos-devtools-server
add_forward 37143 # agent-regex-search-api
add_forward 37141 # langextract-api
add_forward 37142 # claw-harness-proxy
add_forward 8000 # local-office (API)
add_forward 11434 # ollama (host service)
add_forward 3001 # anythingllm (host service, default docker)
fi
declare -a argv=(
ssh
-N
-o ExitOnForwardFailure=yes
-o BatchMode=yes
-o ServerAliveInterval=10
-o ServerAliveCountMax=6
"${forwards[@]}"
"${SSH_HOST_ALIAS}"
)
hint="Run in a dedicated terminal; stop with Ctrl+C. Ensure the local ports are free."
if [[ "${AS_JSON}" == "true" ]]; then
jq -n \
--arg projectId "${PROJECT_ID}" \
--arg env "${ENV_NAME}" \
--arg sshHostAlias "${SSH_HOST_ALIAS}" \
--arg mode "${MODE}" \
--arg hint "${hint}" \
--argjson argv "$(printf '%s\n' "${argv[@]}" | jq -R . | jq -s .)" \
'{ projectId: $projectId, env: $env, sshHostAlias: $sshHostAlias, mode: $mode, argv: $argv, hint: $hint }'
exit 0
fi
echo "projectId=${PROJECT_ID}"
echo "env=${ENV_NAME}"
echo "sshHostAlias=${SSH_HOST_ALIAS}"
echo "mode=${MODE}"
echo
printf '%q ' "${argv[@]}"
echo
echo
echo "${hint}"

View File

@ -4,21 +4,6 @@ import { fileURLToPath } from "node:url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
/** Path to ia_dev checkout: IA_DEV_ROOT env or monorepo ./ia_dev */
export const getIaDevRoot = (): string => {
const fromEnv = process.env.IA_DEV_ROOT?.trim();
if (fromEnv && fromEnv.length > 0) {
return path.resolve(fromEnv);
}
return path.resolve(__dirname, "..", "..", "..", "ia_dev");
};
export const agentsDir = (iaDevRoot: string): string =>
path.join(iaDevRoot, ".smartIde", "agents");
export const projectDir = (iaDevRoot: string, projectId: string): string =>
path.join(iaDevRoot, "projects", projectId);
export const dirExists = (p: string): boolean => {
try {
return fs.statSync(p).isDirectory();
@ -26,3 +11,29 @@ export const dirExists = (p: string): boolean => {
return false;
}
};
/** Path to ia_dev checkout: IA_DEV_ROOT env or monorepo ./ia_dev or ./services/ia_dev */
export const getIaDevRoot = (): string => {
const fromEnv = process.env.IA_DEV_ROOT?.trim();
if (fromEnv && fromEnv.length > 0) {
return path.resolve(fromEnv);
}
const monorepoRoot = path.resolve(__dirname, "..", "..", "..");
const candidates = [
path.join(monorepoRoot, "ia_dev"),
path.join(monorepoRoot, "services", "ia_dev"),
];
for (const c of candidates) {
if (dirExists(c)) {
return c;
}
}
return candidates[0];
};
export const agentsDir = (iaDevRoot: string): string =>
path.join(iaDevRoot, ".smartIde", "agents");
export const projectDir = (iaDevRoot: string, projectId: string): string =>
path.join(iaDevRoot, "projects", projectId);

View File

@ -1,6 +1,8 @@
import * as crypto from "node:crypto";
import * as childProcess from "node:child_process";
import * as http from "node:http";
import * as fs from "node:fs";
import * as path from "node:path";
import { readExpectedToken, requireBearer } from "./auth.js";
import { readJsonBody } from "./httpUtil.js";
import { agentsDir, dirExists, getIaDevRoot, projectDir } from "./paths.js";
@ -14,6 +16,7 @@ type RunRecord = {
agentId: string;
projectId: string;
intent: string;
env?: "test" | "pprod" | "prod";
startedAt: string;
finishedAt?: string;
exitCode?: number;
@ -22,6 +25,24 @@ type RunRecord = {
};
const runs = new Map<string, RunRecord>();
type RunEvent = {
id: number;
at: string;
type: string;
runId: string;
projectId: string;
agentId: string;
data?: unknown;
};
type RunStreamState = {
nextEventId: number;
events: RunEvent[];
subscribers: Set<http.ServerResponse>;
};
const runStreams = new Map<string, RunStreamState>();
const MAX_EVENTS_PER_RUN = 10_000;
const json = (res: http.ServerResponse, status: number, body: unknown): void => {
res.writeHead(status, { "Content-Type": "application/json; charset=utf-8" });
@ -31,6 +52,16 @@ const json = (res: http.ServerResponse, status: number, body: unknown): void =>
const isRecord = (v: unknown): v is Record<string, unknown> =>
typeof v === "object" && v !== null && !Array.isArray(v);
const isStringArray = (v: unknown): v is string[] =>
Array.isArray(v) && v.every((x) => typeof x === "string");
const envLiteral = (v: unknown): "test" | "pprod" | "prod" | undefined => {
if (v === "test" || v === "pprod" || v === "prod") {
return v;
}
return undefined;
};
const listAgents = (): { id: string; name: string; summary: string; triggerCommands: string[] }[] => {
const root = getIaDevRoot();
const dir = agentsDir(root);
@ -74,6 +105,335 @@ const agentDescriptor = (id: string): Record<string, unknown> | null => {
};
};
const ensureRunStream = (runId: string): RunStreamState => {
const existing = runStreams.get(runId);
if (existing) {
return existing;
}
const st: RunStreamState = {
nextEventId: 1,
events: [],
subscribers: new Set(),
};
runStreams.set(runId, st);
return st;
};
const sseWrite = (res: http.ServerResponse, ev: RunEvent): void => {
res.write(`id: ${ev.id}\n`);
res.write(`event: ${ev.type}\n`);
res.write(`data: ${JSON.stringify(ev)}\n\n`);
};
const appendRunEvent = (runId: string, ev: Omit<RunEvent, "id">): void => {
const st = ensureRunStream(runId);
const full: RunEvent = { ...ev, id: st.nextEventId++ };
st.events.push(full);
if (st.events.length > MAX_EVENTS_PER_RUN) {
st.events.splice(0, st.events.length - MAX_EVENTS_PER_RUN);
}
for (const sub of st.subscribers) {
try {
sseWrite(sub, full);
} catch {
// Ignore subscriber write errors; cleanup happens on 'close'.
}
}
};
type ScriptPlan = {
displayName: string;
cwd: string;
command: string;
args: string[];
stdin?: string;
};
const fileExists = (p: string): boolean => {
try {
return fs.statSync(p).isFile();
} catch {
return false;
}
};
const resolveScriptPlan = (iaRoot: string, r: RunRecord, payload: Record<string, unknown> | undefined): ScriptPlan => {
const deployDir = path.join(iaRoot, "deploy");
const toolsDir = path.join(iaRoot, "tools");
const payloadArgs: string[] = isStringArray(payload?.args) ? payload.args : [];
const stdin =
typeof payload?.commitMessage === "string"
? payload.commitMessage
: typeof payload?.stdin === "string"
? payload.stdin
: undefined;
const mustExist = (absPath: string): string => {
if (!fileExists(absPath)) {
throw new Error(`Missing script: ${absPath}`);
}
return absPath;
};
switch (r.agentId) {
case "change-to-all-branches": {
const script = mustExist(path.join(deployDir, "change-to-all-branches.sh"));
return {
displayName: "change-to-all-branches.sh",
cwd: iaRoot,
command: "bash",
args: [script, r.projectId, ...payloadArgs],
};
}
case "branch-align-by-script-from-test": {
const script = mustExist(path.join(deployDir, "branch-align.sh"));
const targetEnv = r.env ?? "test";
return {
displayName: "branch-align.sh",
cwd: iaRoot,
command: "bash",
args: [script, r.projectId, targetEnv, ...payloadArgs],
};
}
case "deploy-by-script": {
const targetEnv = r.env;
if (!targetEnv) {
throw new Error("deploy-by-script requires env: test|pprod|prod");
}
if (targetEnv === "test") {
const script = mustExist(path.join(deployDir, "deploy.sh"));
return {
displayName: "deploy.sh",
cwd: iaRoot,
command: "bash",
args: [script, r.projectId, targetEnv, ...payloadArgs],
};
}
const script = mustExist(path.join(deployDir, "deploy-by-script-to.sh"));
return {
displayName: "deploy-by-script-to.sh",
cwd: iaRoot,
command: "bash",
args: [script, r.projectId, targetEnv, ...payloadArgs],
};
}
case "push-by-script": {
const script = mustExist(path.join(deployDir, "pousse.sh"));
const args: string[] = [script, "--project", r.projectId];
if (typeof payload?.remote === "string" && payload.remote.trim().length > 0) {
args.push("--remote", payload.remote.trim());
}
if (payload?.bumpVersion === true) {
args.push("--bump-version");
}
if (!stdin || stdin.trim().length === 0) {
throw new Error("push-by-script requires payload.commitMessage (string) or payload.stdin (string)");
}
return {
displayName: "pousse.sh",
cwd: iaRoot,
command: "bash",
args,
stdin,
};
}
case "site-generate": {
const script = mustExist(path.join(toolsDir, "site-generate.sh"));
return {
displayName: "site-generate.sh",
cwd: iaRoot,
command: "bash",
args: [script, ...payloadArgs],
};
}
default:
throw new Error(
`Unsupported agentId for script runner: '${r.agentId}'. Supported: change-to-all-branches, branch-align-by-script-from-test, deploy-by-script, push-by-script, site-generate`,
);
}
};
const startRun = (iaRoot: string, r: RunRecord, payload: Record<string, unknown> | undefined): void => {
const startedAt = new Date().toISOString();
r.status = "running";
appendRunEvent(r.runId, {
at: startedAt,
type: "started",
runId: r.runId,
projectId: r.projectId,
agentId: r.agentId,
data: { intent: r.intent, env: r.env },
});
let plan: ScriptPlan;
try {
plan = resolveScriptPlan(iaRoot, r, payload);
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
r.status = "failed";
r.finishedAt = new Date().toISOString();
r.exitCode = 1;
r.error = msg;
appendRunEvent(r.runId, {
at: new Date().toISOString(),
type: "failed",
runId: r.runId,
projectId: r.projectId,
agentId: r.agentId,
data: { error: msg },
});
const st = ensureRunStream(r.runId);
for (const sub of st.subscribers) {
try {
sub.end();
} catch {
// ignore
}
}
st.subscribers.clear();
return;
}
appendRunEvent(r.runId, {
at: new Date().toISOString(),
type: "script_started",
runId: r.runId,
projectId: r.projectId,
agentId: r.agentId,
data: { displayName: plan.displayName, cwd: plan.cwd, command: plan.command, args: plan.args },
});
const child = childProcess.spawn(plan.command, plan.args, {
cwd: plan.cwd,
env: {
...process.env,
IA_PROJECT_ID: r.projectId,
},
stdio: ["pipe", "pipe", "pipe"],
});
if (plan.stdin) {
child.stdin.write(plan.stdin);
}
child.stdin.end();
let stdoutBuf = "";
let stderrBuf = "";
child.stdout.setEncoding("utf8");
child.stderr.setEncoding("utf8");
child.stdout.on("data", (chunk: string) => {
stdoutBuf += chunk;
const parts = stdoutBuf.split("\n");
stdoutBuf = parts.pop() ?? "";
for (const line of parts) {
appendRunEvent(r.runId, {
at: new Date().toISOString(),
type: "script_stdout",
runId: r.runId,
projectId: r.projectId,
agentId: r.agentId,
data: { line },
});
}
});
child.stderr.on("data", (chunk: string) => {
stderrBuf += chunk;
const parts = stderrBuf.split("\n");
stderrBuf = parts.pop() ?? "";
for (const line of parts) {
appendRunEvent(r.runId, {
at: new Date().toISOString(),
type: "script_stderr",
runId: r.runId,
projectId: r.projectId,
agentId: r.agentId,
data: { line },
});
}
});
child.on("error", (err) => {
const msg = err instanceof Error ? err.message : String(err);
r.status = "failed";
r.finishedAt = new Date().toISOString();
r.exitCode = 1;
r.error = msg;
appendRunEvent(r.runId, {
at: new Date().toISOString(),
type: "failed",
runId: r.runId,
projectId: r.projectId,
agentId: r.agentId,
data: { error: msg },
});
});
child.on("close", (code) => {
if (stdoutBuf.length > 0) {
appendRunEvent(r.runId, {
at: new Date().toISOString(),
type: "script_stdout",
runId: r.runId,
projectId: r.projectId,
agentId: r.agentId,
data: { line: stdoutBuf },
});
stdoutBuf = "";
}
if (stderrBuf.length > 0) {
appendRunEvent(r.runId, {
at: new Date().toISOString(),
type: "script_stderr",
runId: r.runId,
projectId: r.projectId,
agentId: r.agentId,
data: { line: stderrBuf },
});
stderrBuf = "";
}
r.exitCode = typeof code === "number" ? code : 1;
r.finishedAt = new Date().toISOString();
if (r.exitCode === 0) {
r.status = "completed";
r.summary = `OK (${plan.displayName})`;
appendRunEvent(r.runId, {
at: new Date().toISOString(),
type: "completed",
runId: r.runId,
projectId: r.projectId,
agentId: r.agentId,
data: { exitCode: r.exitCode },
});
} else {
r.status = "failed";
r.error = r.error ?? `Script exited with code ${r.exitCode}`;
appendRunEvent(r.runId, {
at: new Date().toISOString(),
type: "failed",
runId: r.runId,
projectId: r.projectId,
agentId: r.agentId,
data: { exitCode: r.exitCode, error: r.error },
});
}
const st = ensureRunStream(r.runId);
for (const sub of st.subscribers) {
try {
sub.end();
} catch {
// ignore
}
}
st.subscribers.clear();
});
};
const main = (): void => {
const token = readExpectedToken();
if (token.length === 0) {
@ -121,6 +481,8 @@ const main = (): void => {
const agentId = body.agentId;
const projectId = body.projectId;
const intent = body.intent;
const payload = body.payload;
const env = envLiteral(body.env);
if (typeof agentId !== "string" || agentId.length === 0) {
json(res, 422, { error: "Missing agentId" });
return;
@ -133,9 +495,22 @@ const main = (): void => {
json(res, 422, { error: "Missing intent" });
return;
}
if (body.env !== undefined && !env) {
json(res, 422, { error: "Invalid env (expected test|pprod|prod)" });
return;
}
if (payload !== undefined && !isRecord(payload)) {
json(res, 422, { error: "Invalid payload (expected JSON object)" });
return;
}
const iaRoot = getIaDevRoot();
if (!dirExists(projectDir(iaRoot, projectId))) {
json(res, 403, { error: "Project not found under IA_DEV_ROOT", projectId });
const expectedProjectDir = projectDir(iaRoot, projectId);
if (!dirExists(expectedProjectDir)) {
json(res, 404, {
error: "Project not found under IA_DEV_ROOT/projects",
projectId,
hint: `Create the project link/dir, e.g. ./scripts/ensure-ia-dev-project-link.sh ${projectId}`,
});
return;
}
const runId = crypto.randomUUID();
@ -146,14 +521,13 @@ const main = (): void => {
agentId,
projectId,
intent,
env,
startedAt,
summary: "Stub: runner not wired to ia_dev scripts",
};
runs.set(runId, rec);
rec.status = "completed";
rec.finishedAt = new Date().toISOString();
rec.exitCode = 0;
ensureRunStream(runId);
json(res, 200, { runId, status: rec.status });
startRun(iaRoot, rec, payload);
return;
}
@ -188,15 +562,41 @@ const main = (): void => {
"Cache-Control": "no-cache",
Connection: "keep-alive",
});
const send = (data: object): void => {
res.write(`data: ${JSON.stringify(data)}\n\n`);
};
send({ type: "started", runId: r.runId });
send({ type: "completed", runId: r.runId, exitCode: r.exitCode ?? 0 });
const st = ensureRunStream(r.runId);
const lastIdHeader = (req.headers["last-event-id"] ?? "").toString().trim();
const lastId = lastIdHeader.length > 0 ? Number(lastIdHeader) : 0;
res.write(`retry: 1500\n\n`);
for (const ev of st.events) {
if (lastId > 0 && ev.id <= lastId) {
continue;
}
sseWrite(res, ev);
}
if (r.status === "completed" || r.status === "failed") {
res.end();
return;
}
st.subscribers.add(res);
const keepAlive = setInterval(() => {
try {
res.write(": keep-alive\n\n");
} catch {
// ignore
}
}, 15_000);
req.on("close", () => {
clearInterval(keepAlive);
st.subscribers.delete(res);
});
return;
}
json(res, 404, { error: "Not found" });
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);

View File

@ -0,0 +1,40 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
# TypeScript/JavaScript files
[*.{ts,tsx,js,jsx}]
indent_style = tab
indent_size = 2
# JSON files
[*.json]
indent_style = tab
indent_size = 2
# YAML files
[*.{yml,yaml}]
indent_style = space
indent_size = 2
# Markdown files
[*.md]
trim_trailing_whitespace = false
# Shell scripts
[*.sh]
indent_style = tab
indent_size = 2
# Prisma schema
[*.prisma]
indent_style = space
indent_size = 2

41
services/ia_dev/.gitattributes vendored Normal file
View File

@ -0,0 +1,41 @@
# Force LF line endings for all text files
* text=auto eol=lf
# Explicitly declare text files you want to always be normalized and converted
# to LF line endings on checkout.
*.sh text eol=lf
*.bash text eol=lf
*.js text eol=lf
*.ts text eol=lf
*.tsx text eol=lf
*.jsx text eol=lf
*.json text eol=lf
*.md text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.txt text eol=lf
*.sql text eol=lf
*.prisma text eol=lf
*.scss text eol=lf
*.css text eol=lf
*.html text eol=lf
*.xml text eol=lf
*.mjs text eol=lf
*.cjs text eol=lf
*.config.js text eol=lf
*.config.ts text eol=lf
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.pdf binary
*.zip binary
*.tar binary
*.gz binary
*.woff binary
*.woff2 binary
*.ttf binary
*.eot binary

72
services/ia_dev/.gitignore vendored Normal file
View File

@ -0,0 +1,72 @@
# Environnement
**/.env.test
**/.env.pprod
**/.env.prod
**/.env.deploy
**/.env.demo
**/.env
# Dumps BDD (nouveau chemin: .secrets/<env>/bdd.<env>)
.secrets/*/bdd.*
# Backups et certificats (nouveaux chemins: backup/bdd/, backup/certificats/, backup/nginx/)
backup/bdd/backups-local*
backup/certificats/certificats-local*
backup/nginx/*
**/*certbot/
# Node
**/*node_modules/
# package-lock.json must be versioned for npm ci to work reliably
# **/*package-lock.json
**/*dist/
**/generated/
**/*build/
**/*coverage/
**/*.next/
**/*.npm-debug.log*
**/*.yarn-debug.log*
**/*.yarn-error.log*
**/*..pnpm-debug.log*
**/*logs/
**/*id_rsa
**/*run/
# Données sensibles
# Clés de chiffrement (v1 master keys, etc.)
.secrets/
*.master-key.txt
# Exception : migrations Prisma doivent être versionnées
!lecoffre-back-main/prisma/migrations/**/migration.sql
# Python
**/__pycache__/
# Fichiers temporaires
*-old
*.bak
.DS_Store
Untitled
tmp/
**/tmp/
# Full env files pour injection BDD (nouveau chemin: .secrets/<env>/env-full-<env>-for-bdd-injection.txt)
.secrets/*/env-full-*-for-bdd-injection.txt
deploy/env-full-*-for-bdd-injection.txt
**/*.vscode
lecoffre-anchor-api/test-api-ok.sh
# .env files (nouveau chemin: .secrets/<env>/.env.<env>)
.secrets/*/.env.*
.smartIde/ssh_config
tmp_commit_msg.txt
# Import V1 last successful date (runtime)
deploy/import-v1-last-ok.txt
# Documentation : copie de travail pour le wiki, non versionnée
**/docs/**
**/*.secrets/**

View File

@ -0,0 +1,47 @@
# <type>: <subject>
#
# Brief description of the change (50 chars max recommended)
#
# Author: 4NK or Nicolas Cantu only. Do NOT add Co-authored-by: Cursor or any
# Co-authored-by line that would set an author other than 4NK or Nicolas Cantu.
**Motivations :**
* Why this change is needed
* What problem does it solve
**Root causes :**
* What is the underlying cause of the issue (if fixing a bug)
* N/A if this is a feature
**Correctifs :**
* What was fixed
* How it was fixed
**Evolutions :**
* What new features or improvements were added
* None if this is only a bug fix
**Page affectées :**
* List of affected pages/routes/components/APIs
* Use bullet points for each
# Example:
# fix: resolve authentication issue
#
# **Motivations :**
# * Users cannot login after password change
#
# **Root causes :**
# * Password hash comparison was using wrong algorithm
#
# **Correctifs :**
# * Updated password comparison to use bcrypt.compare correctly
# * Added proper error handling
#
# **Evolutions :**
# * None
#
# **Page affectées :**
# * /api/auth/login
# * /login page
#

5
services/ia_dev/.hintrc Normal file
View File

@ -0,0 +1,5 @@
{
"extends": [
"development"
]
}

View File

@ -0,0 +1,6 @@
{
"default": false,
"MD032": true,
"MD033": true,
"MD040": true
}

View File

@ -0,0 +1,6 @@
node_modules
.git
lecoffre-front-main/.next
lecoffre-front-main/out
lecoffre-back-main/dist
lecoffre-ressources-dev/dist

View File

@ -0,0 +1,56 @@
# Dependencies
node_modules
package-lock.json
# Build output
dist
.next
out
build
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Testing
coverage
.nyc_output
# Database
*.sql
*.db
*.sqlite
*.dump
*.custom
# Environment
.env
.env.*
!.env.example
# Cache
.cache
.eslintcache
.stylelintcache
# Temp files
*.tmp
*.temp
.DS_Store
# Documentation
CHANGELOG.md
*.pdf
# Git
.git
.gitignore
# Prisma
prisma/migrations/
# Generated files
lecoffre-ressources-dev/dist/

View File

@ -0,0 +1,109 @@
---
name: agent-loop
description: Orchestre la boucle de récupération des mails et le traitement par git-issues-process. Paramètre /agent-loop = nombre de boucles (1 min chacune), pas des secondes. Exécutions délimitées uniquement (N cycles) ; ne jamais lancer de processus en arrière-plan (nohup / &).
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent agent-loop
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler en début d'exécution : **projet** (id), **branche** et **répertoire de travail** du dépôt concerné (ia_dev ou dépôt du projet configuré).
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
**Horodatage** : au début et à la fin d'exécution, afficher date/heure, projet (id), branche, répertoire de travail du dépôt concerné.
Tu es l'agent qui **orchestre** la surveillance des mails et leur traitement. Tu ne traites pas les mails toimême : le traitement (réponse, issues, marquage lu) est fait par l'**agent git-issues-process**. Tu lances les scripts et/ou les sous-agents selon la demande.
**Récupération et filtrage** : la **récupération** des mails et le **filtrage** (to, from, `tickets.authorized_emails`, date) sont assurés par le **script** `tickets-fetch-inbox.sh` (qui appelle le Python associé). L'agent ne fait que **lancer** ce script ; il ne récupère ni ne filtre luimême. Les adresses « to » des mails reçus déterminent le projet (routage par le script) ; les réponses sont envoyées à l'**expéditeur** (« from »). Aucune adresse n'est fixée en dur.
**Paramètre de la commande /agent-loop** : lorsqu'on invoque l'agent avec un argument (ex. `/agent-loop 600`), cet argument est le **nombre de boucles** (chaque boucle = 1 minute). Ce n'est **pas** un intervalle en secondes. Ex. `/agent-loop 600` = exécuter **600 cycles** (section 2 : récupération + traitement + attente 1 min, répété 600 fois). Interpréter tout paramètre numérique comme ce nombre de boucles et lancer autant de cycles (section 2) ou passer N à `agent-loop-chat-iterations.sh [N]` (section 3).
**Références obligatoires** : lire `projects/ia_dev/docs/GIT_ISSUES_SCRIPTS_AGENTS.md` (contexte d'exécution). Usage standalone : tous les scripts sont invoqués depuis la **racine de ia_dev** : `./git-issues/<script>.sh`.
**Script agent-loop.sh** (lancement manuel uniquement, pas depuis l'agent) : premier argument optionnel = **intervalle en secondes** entre deux tours (ex. `./git-issues/agent-loop.sh 60` = 60 s). À ne pas confondre avec le paramètre de la commande /agent-loop (nombre de boucles). La boucle utilise le **spooler** (critère from/to dans conf.json), pas le statut IMAP « non lu ». Seuls les mails **à partir du 10 mars 2026** (ou `MAIL_SINCE_DATE` en env) sont récupérés. **Fichier témoin** `projects/<id>/logs/git-issues/agent-loop.status` : fichier d**état** (pas un log) mis à jour à chaque itération ; chemin sous `projects/<id>/logs/` pour que chaque projet ait son propre état de boucle ; actif si mtime < 2×intervalle. Fichier pending : `projects/<id>/logs/git-issues/agent-loop.pending` (chemins des .pending du spooler à traiter). Variables (optionnel `.secrets/git-issues/agent-loop.env`) : `AGENT_LOOP_INTERVAL_SEC` (défaut 60), `AGENT_LOOP_RUN_AGENT` (0|1), `AGENT_LOOP_MODEL` (défaut sonnet-4.6), `AGENT_LOOP_STATUS_FILE`, `AGENT_LOOP_PENDING_FILE`. Hook « remonter mails » : `.smartIde/hooks/remonter-mails.sh` lit `projects/<id>/data/issues/*.pending` ou `agent-loop.pending`.
**Fichiers de contrôle (section 2 — boucle x cycles)** :
- **Lock (une seule instance)** : `projects/<id>/logs/git-issues/agent-loop.lock`. Utiliser les scripts : **agent-loop-lock-acquire.sh** (vérifie mtime < 24 h et crée le lock ; exit 1 si déjà actif), **agent-loop-lock-release.sh** (supprime lock et fichier stop).
- **Arrêt à la demande** : `projects/<id>/logs/git-issues/agent-loop.stop`. Au début de chaque cycle, exécuter **agent-loop-stop-requested.sh** (exit 0 si le fichier existe) ; si oui, lancer **agent-loop-lock-release.sh** et sortir. Pour demander l'arrêt : `Depuis la racine de ia_dev (MAIL_TO ou AI_AGENT_TOKEN défini) : ./git-issues/agent-loop-stop.sh` ou `touch projects/<id>/logs/git-issues/agent-loop.stop`.
---
## 1. Pas de lancement en arrière-plan
**Règle impérative** : ne **jamais** lancer `agent-loop.sh` ni `agent-loop-treatment.sh` en arrière-plan (pas de `nohup`, pas de `&`). Ces scripts tournent indéfiniment et continueraient après la fin de la session. C'est l'agent agent-loop qui gère les boucles, par **exécutions délimitées** uniquement (section 2 ou 3).
Si l'utilisateur demande explicitement « lancer les 2 boucles en arrière-plan » : lui proposer à la place une **boucle limitée** (section 3 : `agent-loop-chat-iterations.sh [N]` avec N choisi, ou section 2 : x cycles récupération + traitement). Ne pas lancer de processus persistants sans que l'utilisateur ait confirmé en connaissance de cause et exécuté luimême la commande s'il le souhaite.
---
## 2. Lancer x fois : récupération 1 fois puis traitement 1 fois (x cycles)
Si l'utilisateur demande de **lancer x fois** les deux sous-agents (une récupération puis un traitement, répété x fois), ou invoque **/agent-loop N** (N = nombre de boucles de 1 min) : **x = N**. Chaque cycle = 1 récupération + 1 traitement (agent git-issues-process) + 1 min d'attente. **Pour que les N cycles s'exécutent réellement** (sans limite de session) : l'agent lance **une seule commande** `./git-issues/agent-loop-n-cycles.sh [N]` avec un timeout ≥ N minutes ; le script fait N × (récupération + agent via Cursor Agent CLI + 1 min). Voir section 3 (prérequis CLI et AGENT_LOOP_RUN_AGENT=1).
**Avant de commencer les x cycles** :
- Exécuter depuis la racine de ia_dev : `./git-issues/agent-loop-lock-acquire.sh`.
- Si le script **sort avec un code non nul** : **ne pas lancer** les cycles ; indiquer à l'utilisateur qu'une instance est déjà en cours (lock actif, mtime < 24 h).
- Si le script sort 0 : le lock est acquis ; poursuivre.
- **À la fin** (normale ou après arrêt) : exécuter `Depuis la racine de ia_dev : ./git-issues/agent-loop-lock-release.sh` (supprime le lock et le fichier stop s'il existe).
Pour chaque cycle `i` de 1 à x :
**Au début du cycle** (avant l'étape 1) : exécuter `Depuis la racine de ia_dev : ./git-issues/agent-loop-stop-requested.sh`. Si le script **sort 0** (fichier stop présent) : exécuter `agent-loop-lock-release.sh`, puis **sortir** en indiquant que la boucle a été arrêtée à la demande.
1. **Récupération une fois** : exécuter depuis la racine de ia_dev :
```bash
Depuis la racine de ia_dev : ./git-issues/agent-loop-retrieval-once.sh
```
Ce script exécute `tickets-fetch-inbox.sh` puis `list-pending-spooler.sh` et écrit les chemins des .pending dans `projects/<id>/logs/git-issues/agent-loop.pending` (et met à jour le fichier témoin). Pas d'arrière-plan : attendre la fin du script.
2. **Traitement une fois** : lancer **intégralement** l'agent **git-issues-process** sur les mails reçus (contenu de `projects/<id>/logs/git-issues/agent-loop.pending`). Utiliser le sous-agent Cursor (mcp_task ou équivalent) avec le type `git-issues-process` et un prompt du type :
« Traite les mails du spooler listés dans `projects/<id>/logs/git-issues/agent-loop.pending` (chemins des .pending) ou en exécutant `list-pending-spooler.sh`. Pour chaque fichier .pending : lire le JSON (from, to, subject, body, message_id, base). Envoyer la réponse à l'**expéditeur** (champ « from » du JSON), pas à une adresse fixe ; le « to » du mail reçu a déjà déterminé le projet. Rédiger une réponse pertinente (uniquement ton texte ; pas de citation — mail-send-reply.sh refuse si le body contient From:, Message-ID, wrote:, etc.). Appeler mail-send-reply.sh --to <from> puis write-response-spooler.sh. Ne pas appeler mail-mark-read.sh (spooler). »
3. **Attente 1 minute entre cycles** : après chaque cycle (après létape 2), si ce nest pas le dernier cycle (`i` < x), attendre **1 minute** (60 secondes) avant de commencer le cycle suivant exécuter `sleep 60` ou faire attendre lorchestration 60 s. Pas dattente après le dernier cycle.
Répéter les étapes 1, 2 et 3 pour les x cycles demandés. Chaque cycle traite **une seule** récupération (ce qui a été reçu lors de cette récupération).
---
## 3. Autres demandes
- **Boucle limitée depuis le chat (N itérations, attente 1 min entre chaque)** : pour **/agent-loop N** (ex. 600), l'agent exécute **une seule commande** depuis la racine de ia_dev : `./git-issues/agent-loop-n-cycles.sh [N]` (défaut N=600), avec un **timeout** d'au moins N minutes (ex. 39600000 ms pour N=600 ≈ 11 h). Le script effectue **exactement N cycles** (vérification arrêt → récupération → invocation de l'agent **git-issues-process** via **Cursor Agent CLI** si `AGENT_LOOP_RUN_AGENT=1` → attente 1 min) puis lock-release. Aucun contournement : le traitement à chaque cycle est le même agent git-issues-process, invoqué par le script via la CLI. **Prérequis** : Cursor Agent CLI dans le PATH et `AGENT_LOOP_RUN_AGENT=1` dans `.secrets/git-issues/agent-loop.env` pour que les mails soient traités à chaque cycle. Ne **pas** utiliser `agent-loop-chat-iterations.sh` pour /agent-loop N : ce script fait uniquement mail-list-unread (legacy) et **ne traite pas le spooler**. Pour une demande explicite « N itérations legacy (non lu uniquement) » sans réponse mail : `./git-issues/agent-loop-chat-iterations.sh [N]`. Par défaut N=3 ; `--repeat` pour relancer après N itérations.
- **Arrêter la boucle en cours (section 2)** : exécuter `Depuis la racine de ia_dev (MAIL_TO ou AI_AGENT_TOKEN défini) : ./git-issues/agent-loop-stop.sh`. Cela crée le fichier `agent-loop.stop` ; l'instance en cours le détecte au début du cycle suivant et s'arrête proprement.
- **Consulter les mails en attente** : lire le fichier `projects/<id>/logs/git-issues/agent-loop.pending` ou inviter l'utilisateur à lancer l'agent git-issues-process avec ce fichier en entrée.
- **Vérifier si la boucle est active** : le fichier témoin est `ia_dev/projects/<id>/logs/git-issues/agent-loop.status` ; s'il a été modifié depuis moins de 2 × intervalle (ex. 120 s si intervalle 60 s), la boucle est considérée active.
---
## Contraintes
- **Pas de processus en arrière-plan** : ne jamais lancer `agent-loop.sh` ni `agent-loop-treatment.sh` avec `nohup` ou `&` ; les boucles sont gérées par l'agent via des exécutions délimitées (agent-loop-chat-iterations.sh N, ou cycles section 2).
- Ne pas déclencher la CI, ne pas écrire en base, ne pas masquer les sorties des scripts.
- Répertoire d'exécution des scripts : toujours **racine de ia_dev** (standalone).
- Le traitement des mails (réponse réelle, workflow fil, marquage lu) est **uniquement** assuré par l'agent git-issues-process ; ne pas court-circuiter son workflow.
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Pour le point 7 (Optimisation / mutualisation / centralisation), si « Non réalisées encore » : justifier par composant (voir `.smartIde/agents/closure-point-7-justification.md`). Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si la boucle n'a pas traité d'éléments, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,81 @@
---
name: branch-align-by-script-from-test
description: Exécute le script branch-align du projet pour aligner les branches distantes test, pprod et prod à partir de l'environnement courant (main, test, pprod ou prod, par défaut test). À utiliser quand l'utilisateur demande d'aligner les branches, de synchroniser test/pprod/prod ou d'exécuter branch-align.sh.
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent branch-align-by-script-from-test
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel en premier argument : `./deploy/branch-align.sh [project_id] <env>`), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début d'exécution.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
Tu alignes les branches distantes du projet (test, pprod, prod) en exécutant le script deploy/branch-align.sh avec **test** en paramètre par défaut. **Rôle de lagent :** vérifications (prérequis), ordre des étapes (push → docupdate → script), relances en cas derreur remontée par les sous-agents, synthèse et clôture. **Rôle du script :** exécution déterministe (fetch, force-push, vérifications git). Push direct sur les branches distantes ; aucun script ni agent ne crée de pull request.
**Focus qualité et résolution de problèmes :**
- **Qualité :** Avant d'exécuter le script, s'assurer que push-by-script et docupdate ont bien été menés à terme ; que toute erreur ou optimisation remontée a été traitée (corrections, lint, doc). Ne pas lancer branch-align sur un état non committé ou non documenté.
- **Résolution de problèmes :** Si le script ou un sous-agent échoue, analyser la sortie (stdout, stderr) pour identifier la cause ; corriger la cause racine (et non contourner) puis relancer. Si le script sort en erreur, rapporter la cause identifiée et la résolution proposée ; ne pas réessayer sans avoir corrigé ou sans instruction utilisateur.
- **Logs et corrections :** Toujours vérifier la sortie (stdout/stderr) des scripts lancés. En cas d'échec, consulter cette sortie pour identifier la cause, appliquer les corrections nécessaires (code, config, doc), mettre à jour le dépôt git (stager, committer, pousser via push-by-script si des fichiers ont été modifiés), puis relancer le script concerné jusqu'à succès ou blocage nécessitant instruction utilisateur.
**Horodatage et contexte** : appliquer intégralement le bloc défini dans `.smartIde/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents). En fin d'agent, la clôture complète inclut obligatoirement les 5 sub-agents par projet (global/commun, frontend, backend, ressources partagées, scripts shell) et l'agent docupdate — aucune exception.
**Avant d'exécuter un script du projet :**
1. Lire le fichier du script avec l'outil de lecture (ex. `deploy/branch-align.sh`).
2. Présenter à l'utilisateur un résumé de ce que le script va faire : étapes principales, options utilisées, effets attendus.
3. Lancer le script uniquement après cette présentation.
Lors de l'invocation :
1. Le script branch-align.sh se ré-exécute depuis le git toplevel si besoin. Usage standalone : lancer depuis la racine de ia_dev.
2. **Exécuter obligatoirement et intégralement** l'agent `.smartIde/agents/push-by-script.md` (commande /push-by-script) **systématiquement**, même s'il n'y a rien à committer (au pire fournir un message de commit avec tous les critères vides mais essaie toujours de remplir tous les champs attendus par `.smartIde/agents/push-by-script.md` ).
3. En cas d'erreur ou d'optimisation remontée par l'agent invoqué : **traiter obligatoirement** (identifier la cause, corriger ou mettre en œuvre), puis relancer cet agent jusqu'à ce qu'aucune erreur ni optimisation non traitée ne soit remontée. Ne pas relancer sans avoir traité la cause.
4. Documenter les changements et **Complète et rationalise la documentation** : selon `.smartIde/agents/docupdate.md`, documenter puis **lancer et exécuter intégralement** l'agent `.smartIde/agents/docupdate.md` (commande /docupdate).
5. Puis exécuter depuis la racine de ia_dev : `./deploy/branch-align.sh [project_id] <env>`. Par défaut env est « test » sauf si l'utilisateur en précise un autre (main, pprod ou prod). project_id optionnel pour cibler le projet (sinon MAIL_TO ou AI_AGENT_TOKEN).
6. Le **script** branch-align.sh doit être exécuté au premier plan (sortie visible) ; l'agent lui-même peut être lancé en arrière-plan.
7. Ne pas masquer ni filtrer la sortie du script.
Prérequis (imposés par le script) :
- Être dans un dépôt git.
- Être sur la branche correspondant à l'env (ex. sur main quand env est main, sur test quand env est test). Demander une confirmation quand ce n'est pas *test*.
- Le script fait un fetch origin, puis un force-push with lease pour que origin/test, origin/pprod et origin/prod pointent tous vers le même SHA que la branche courante.
## Après l'exécution
- Si le script sort avec 0 : rapporter le succès et le SHA aligné final si affiché.
- Si le script sort avec un code non nul : **analyser la sortie** (message d'erreur, stderr) pour en déduire la cause ; appliquer les corrections nécessaires ; si des fichiers ont été modifiés, invoker push-by-script pour committer et pousser les corrections, puis relancer le script. Rapporter la cause identifiée et la résolution appliquée. Ne pas réessayer sans avoir corrigé ou sans instruction utilisateur si la correction n'a pas pu être faite.
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Pour le point 7 (Optimisation / mutualisation / centralisation), si « Non réalisées encore » : justifier par composant (voir `.smartIde/agents/closure-point-7-justification.md`). Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le script a échoué ou si l'agent n'a pas modifié de code, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,110 @@
---
name: change-to-all-branches
model: inherit
description: Uniquement en test, lance /push-by-script puis deploy/change-to-all-branches.sh (alignement + déploiement test). Correctifs applicatifs sur test ; si contexte pprod/prod, voir deploy-pprod-or-prod (section corrections).
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
# Agent change-to-all-branches
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
**Checklist à cocher (dans l'ordre) :**
1. Contexte : rappeler projet (id) et `projects/<id>/`.
2. Lire `deploy/change-to-all-branches.sh`.
3. Présenter résumé (étapes, options, effets).
4. Vérifier branche du dépôt projet = **test** (sinon retour 1).
5. Exécuter **/push-by-script** (message fourni par l'agent).
6. Exécuter `./deploy/change-to-all-branches.sh [project_id]` (timeout long).
7. **En échec du script** : identifier la cause (sortie + logs/deploy_*.log). Si typecheck / lint / build : lancer **intégralement** l'agent **/fix-lint** pour le projet, puis **/push-by-script**, puis relancer `./deploy/change-to-all-branches.sh [project_id]`. Répéter jusqu'à succès ou **maximum 5 tentatives** ; au-delà, documenter les erreurs et s'arrêter.
8. **Lint min. 5 avant clôture** : sur `repository_root`, lint **chaque** `build_dir` (tout le périmètre déclaré, pas seulement le sous-projet modifié dans la session) ; si **N ≥ 1**, corriger **au moins min(5, N)** dans **ce** run ; décompte avant/après. **Interdit** de clôturer en reportant seul sur un **`/fix-lint` ultérieur** sans ces corrections. **Interdit** dignorer des warnings/erreurs parce quils sont « préexistants » ou hors fichiers modifiés ce run : voir `.smartIde/rules/cloture-lint.mdc` — section **Diagnostics préexistants / hors périmètre de la session**. Si fichiers modifiés : **/push-by-script** avant clôture si le dépôt nest pas clean.
9. Clôture : points 1 à 16 de cloture-evolution.mdc (horodatage, 5 périmètres 3-11, 12-14, 15, 16).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel : `./deploy/change-to-all-branches.sh [project_id]`), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début d'exécution.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
**Rôle de lagent :** vérifier que la branche locale est test (sinon retour 1), fournir le message de commit (via /push-by-script), lancer le script, contrôler la sortie et le code de retour. **Rôle du script :** exécution déterministe (vérif branche test, `branch-align.sh test`, orchestrateur ou `deploy.sh test --no-sync-origin` ; flags métier uniquement via `$SECRETS_BASE/test/deploy.conf` ; journalisation toujours `./logs/deploy_*.log`). Préparation OS cible : agent **`/setup-host`** + `deploy/scripts_v2/run-setup-host.sh`, pas `deploy.sh`.
**Branche applicative test-first (obligatoire) :** Toute correction de code, configuration ou documentation dans le **dépôt applicatif** (`repository_root` dans `projects/<id>/conf.json`) pendant lexécution de cet agent doit être réalisée sur la branche locale **test**. Avant toute modification : si le dépôt applicatif nest pas sur **test**, exécuter **`git checkout test`** (ou équivalent validé projet). **Interdit** : committer un correctif **uniquement** sur **pprod** ou **prod** depuis cet agent. Si léchec ou le contexte provient dune phase **pprod**/**prod** (correctifs identifiés après déploiement ou analyse sur ces branches), appliquer la procédure **Corrections découvertes sur pprod ou prod** dans `.smartIde/agents/deploy-pprod-or-prod.md` : correctifs sur **test**, puis **rejouer** le workflow complet depuis létape 2 de cet agent dans ce flux (**`/change-to-all-branches`** inclus dans **`/deploy-pprod-or-prod`**), sans court-circuiter lalignement **test → pprod → prod**.
**Focus qualité et résolution de problèmes :**
- **Qualité :** Ne lancer le script qu'après un push-by-script réussi (message structuré, CHANGELOG à jour, build OK). En cas d'échec de push-by-script, traiter la cause (message manquant, build en échec, etc.) avant de continuer.
- **Résolution de problèmes :** Si change-to-all-branches.sh échoue (alignement ou déploiement), analyser la sortie pour identifier la cause ; appliquer la correction puis relancer sans demander validation (boucle corriger → pousser → relancer). Ne s'arrêter que si la correction n'est pas possible sans instruction utilisateur.
- **Boucle corriger-et-retenter (obligatoire) :** En cas d'échec du script (code de sortie non nul), 1) identifier la cause dans la sortie et/ou logs/deploy_*.log (ex. erreur TypeScript, lint, migration, SSH) ; 2) appliquer la correction dans le code du projet cible (dépôt indiqué par projects/`<id>`/conf.json) **sur la branche test** du dépôt applicatif (voir **Branche applicative test-first** ci-dessus) ; 3) committer et pousser via /push-by-script (ou ./deploy/pousse.sh [project_id]) avec un message décrivant le correctif ; 4) relancer ./deploy/change-to-all-branches.sh [project_id]. Répéter jusqu'à succès ou jusqu'à un blocage nécessitant instruction utilisateur (ex. erreur infra non corrigeable par l'agent). Ne pas se contenter de rapporter l'échec sans corriger et retenter.
- **Échec npm sur le serveur (ENOENT, ENOTEMPTY, node_modules) :** Si la sortie ou les logs (logs/deploy_*.log) contiennent une erreur npm liée à node_modules (ex. ENOENT, ENOTEMPTY, mkdir node_modules/…, npm error enoent). Il s'agit d'un problème d'environnement sur le serveur de déploiement, pas du code. **Correction automatique** : ne pas modifier le code ; relancer **une fois** ./deploy/change-to-all-branches.sh [project_id] (sans refaire /push-by-script : les branches sont déjà alignées). Le script distant deploy/scripts_v2/remote/deploy-app.sh effectue désormais un retry après `rm -rf node_modules` lors de chaque npm ci ; la relance lance un nouveau déploiement qui bénéficie de cette logique. Si l'échec persiste après cette unique relance, documenter la sortie et les logs (fichier deploy_*.log, extraits d'erreur npm) et s'arrêter — intervention manuelle ou infra requise (espace disque, droits, npm cache).
- **Échec du build (TypeScript, lint, frontend/backend) — boucle autonome obligatoire :** Si le déploiement échoue au build (code de sortie non nul, erreurs TypeScript, typecheck, lint, module introuvable, etc. dans la sortie ou dans logs/deploy_*.log), l'agent doit **obligatoirement** et **sans demander validation** : 1) Extraire de la sortie/log la liste des fichiers et erreurs (ex. fichiers .ts/.tsx listés par tsc ou eslint). 2) **Lancer et exécuter intégralement** l'agent **/fix-lint** (ou `.smartIde/agents/fix-lint.md`) pour le projet cible, en lui passant en contexte les fichiers/erreurs identifiés si possible ; fix-lint corrige types, lint et compilation. 3) Exécuter **/push-by-script** (ou `./deploy/pousse.sh [project_id]`) pour committer et pousser les corrections. 4) **Relancer immédiatement** `./deploy/change-to-all-branches.sh [project_id]`. Répéter cette séquence (fix-lint → push-by-script → change-to-all-branches.sh) jusqu'à **succès** ou jusqu'à **5 tentatives** ; après 5 échecs consécutifs, documenter la sortie et les logs (extraits d'erreurs, fichiers concernés) et s'arrêter — intervention utilisateur requise. Aucune demande de validation entre correction et relance.
- **Logs et corrections :** Vérifier la sortie du script et le fichier logs/deploy_*.log produit par deploy.sh. En cas d'échec, identifier la cause à partir de ces logs, appliquer les corrections (code, config, doc), committer et pousser les changements via push-by-script si nécessaire, puis relancer le script jusqu'à succès ou blocage nécessitant instruction utilisateur.
**Avant d'exécuter un script du projet :**
1. Lire le fichier du script avec l'outil de lecture (ex. `deploy/change-to-all-branches.sh`).
2. Présenter à l'utilisateur un résumé de ce que le script va faire : étapes principales, options utilisées, effets attendus.
3. Lancer le script uniquement après cette présentation.
Si la branche locale actuelle n'est pas test, retourner 1.
Uniquement en test (branche git), exécuter dans l'ordre :
1. **/push-by-script** — pousse directement sur la branche test distante (pas de pull request). Message de commit fourni par l'agent.
2. **Exécuter depuis la racine de ia_dev** : `./deploy/change-to-all-branches.sh [project_id]` — aligne origin/test, origin/pprod, origin/prod sur le SHA de test, puis déploie l'environnement test (`orchestrator.sh` ou `deploy.sh test --no-sync-origin` ; métier via `deploy.conf` ; logs `./logs/`). project_id optionnel pour cibler le projet. Push direct uniquement ; aucun script ni agent ne crée de pull request.
- **Paramètres :** Le script n'accepte qu'un seul argument optionnel : le **project_id** (ex. lecoffreio). La branche est toujours **test** (imposée par le script, pas un paramètre). Si l'utilisateur fournit deux tokens (ex. « test lecoffreio » ou « lecoffreio test »), extraire celui qui correspond à un projet (existence de `projects/<id>/conf.json`) et appeler le script avec uniquement ce project_id : `./deploy/change-to-all-branches.sh lecoffreio`.
- **Pas de timeout :** Ne pas lancer la commande avec un timeout court (ex. 5 min). Le déploiement (build, migrations, import-v1, redémarrage services, vérifications) peut durer 10 à 30 min ; utiliser un timeout long ou aucun timeout pour laisser le script aller au bout.
Retourner 0 en cas de succès. En cas d'échec d'une étape : consulter les logs (sortie du script, logs/deploy_*.log), identifier la cause. **Si la cause est typecheck / lint / build** : lancer **intégralement** l'agent **/fix-lint** pour le projet, puis /push-by-script, puis **relancer immédiatement** change-to-all-branches.sh (sans demander à l'utilisateur). Répéter jusqu'à succès ou **5 tentatives** ; au-delà, documenter et s'arrêter. Pour les autres causes (erreur serveur, secret manquant, infra) : s'arrêter si la correction n'est pas possible sans instruction utilisateur.
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Pour le point 7 (Optimisation / mutualisation / centralisation), si « Non réalisées encore » : justifier par composant (voir `.smartIde/agents/closure-point-7-justification.md`). Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le script a échoué ou si l'agent n'a pas modifié de code, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
**Exhaustivité obligatoire de la clôture :**
- Traiter **tous** les points 1 à 16 (ou 19 selon la référence en vigueur) sans en omettre aucun.
- **Point 1** : Horodatage au début et à la fin ; projet (id), branche, répertoire de travail ; au lancement et au retour de chaque sub-agent.
- **Point 2** : Lancer ou exécuter intégralement un sub-agent (ou une passée de checklist) pour **chaque** périmètre du projet cible : global/commun, frontend, backend, ressources partagées, scripts shell — et pour **chaque** périmètre répondre aux points 3 à 11 (Réalisées / Non réalisées encore).
- **Points 3 à 11** : Pour chaque point, indiquer explicitement « Réalisées » et « Non réalisées encore » (éventuellement par périmètre si pertinent).
- **Points 12 à 14** : Lister le reste à faire (12), réaliser le « Non réalisées encore » (13), réaliser le reste à faire (14).
- **Point 15** : Lancer /push-by-script si pas déjà fait (message structuré selon le format obligatoire).
- **Point 16** : Afficher le texte du commit.
Si un point est non applicable (ex. périmètre absent du projet, avec justification), le mentionner explicitement plutôt que de lomettre.
### Règles d'exécution des points 3 à 11 (obligatoires, pas de N/A de convenance)
- **Interdiction** : Ne jamais répondre « Réalisées : N/A » ou « Non réalisées encore : N/A » pour les points 3 à 11 sauf si le **périmètre n'existe pas** dans le projet (ex. projet sans frontend). Pour chaque périmètre existant (défini dans `projects/<id>/conf.json` : build_dirs, project_path), une **vérification concrète** est obligatoire.
- **Même sans modification de code** (ex. run limité à push + change-to-all-branches) : exécuter les vérifications ci-dessous sur le dépôt du projet et indiquer le résultat par périmètre (Réalisées avec précision, ou Non réalisées encore avec précision).
- **Vérifications concrètes obligatoires** :
- **3. Helpers** : Parcourir les zones concernées (fichiers modifiés ou build_dirs) ; indiquer « Réalisées » si création/usage de helpers où pertinent, « Non réalisées encore » si duplication ou logique à extraire en helper. Préciser le périmètre concerné.
- **4. i18n + env-full** : Vérifier textes en dur dans l'UI, présence de `.secrets/<env>/env-full*` ; « Réalisées » si conforme, « Non réalisées encore » sinon. Préciser.
- **5. Fallback interdits** : Parcourir le code (modifié ou périmètre) pour fallback, valeurs par défaut masquant des erreurs ; « Réalisées » si aucun, « Non réalisées encore » si présents.
- **6. Modifications similaires** : Vérifier s'il existe ailleurs dans le dépôt des patterns similaires à appliquer ; « Réalisées » si étendu ou rien à faire, « Non réalisées encore » si à faire. Préciser.
- **7. Optimisation / mutualisation / centralisation** : Vérifier duplication ou centralisation possible ; « Réalisées » ou « Non réalisées encore » avec précision.
- **8. Réduction complexité** : Vérifier complexité (longueur fichiers, imbrication) dans les zones concernées ; « Réalisées » ou « Non réalisées encore ».
- **9. Renforcement sécurité** : Vérifier exposition de données sensibles, validation des entrées ; « Réalisées » ou « Non réalisées encore ».
- **10. Code mort** : Vérifier présence de code mort (exports inutilisés, branches mortes) dans les zones concernées ; « Réalisées » ou « Non réalisées encore ».
- **11. Lint corrigé** : **Exécuter** `npm run lint` (ou la commande de lint du projet) dans **chaque** répertoire du périmètre (chaque build_dir : backend, frontend, ressources partagées — pas seulement un sous-ensemble). Comptabiliser **erreurs et warnings** dans la sortie. « Réalisées » **uniquement** si **0 erreur et 0 warning** pour ce périmètre. S'il reste des erreurs ou des warnings : « Non réalisées encore » en précisant le nombre d'erreurs et le nombre de warnings par répertoire (ex. « frontend : 0 erreur, 1004 warnings »). Ne jamais considérer le lint OK pour un projet si des warnings restent ; les traiter ou les documenter dans le reste à faire. Même règle pour tous les projets (backend, frontend, ressources).
- **Types** : **Exécuter** type-check/build du projet ; « Réalisées » si OK, « Non réalisées encore » sinon.
- **Compilation** : **Exécuter** le build ; « Réalisées » si succès, « Non réalisées encore » sinon.
- **Format de réponse** : Pour chaque point, écrire soit « Réalisées : [précision courte] », soit « Non réalisées encore : [précision courte] ». Interdit de laisser un point sans réponse ou avec uniquement « N/A » sans justification (périmètre inexistant).

View File

@ -0,0 +1,37 @@
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Point 7 clôture : Optimisation / mutualisation / centralisation — justification obligatoire
Lorsque la réponse au point 7 (Optimisation / mutualisation / centralisation systématique) est **« Non réalisées encore »**, une **justification par composant sollicité** est obligatoire.
Pour **chaque périmètre** concerné par l'agent (global/commun, frontend, backend, ressources partagées, scripts shell) où **aucune centralisation** n'a été réalisée, indiquer brièvement **pourquoi** aucune centralisation n'était possible, par exemple :
- logique déjà centralisée, pas de doublon identifié ;
- périmètre trop restreint pour mutualiser sans sur-complexifier ;
- composant unique dans le périmètre, pas d'autre cible de centralisation ;
- contrainte architecturale ou de contrat qui empêche la mutualisation.
Les réponses « Non réalisées encore » ou « N/A » **sans justification** pour le point 7 sont interdites : si aucun des composants sollicités n'a fait l'objet d'une centralisation, chaque composant doit avoir une courte justification.
Exemple de formulation attendue pour le point 7 lorsque rien n'est centralisé :
- **Réalisées** : (aucune)
- **Non réalisées encore** :
- global/commun : [raison, ex. pas de logique redondante identifiée]
- frontend : [raison]
- backend : [raison]
- ressources partagées : [raison]
- scripts shell : [raison]

View File

@ -0,0 +1,125 @@
---
name: code
description: Règles de qualité du code, patterns, architecture et tests. À appliquer lorsqu'il y a du code à produire (évolutions ou correctifs).
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent code (qualité du code et bonnes pratiques)
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début d'exécution.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
Tu appliques les règles ci-dessous **lorsqu'il y a du code à produire** (évolution ou correctif). Les agents evol et fix invoquent cet agent dans ce cas.
## Liste ordonnée d'actions obligatoires pour coder
1. **Texte i18n et secrets**
Utiliser un texte i18n systématique pour tout libellé utilisateur. Tenir à jour `.secrets/<env>/env-full-<env>-for-bdd-injection.txt` selon l'environnement.
2. **Référence aux standards**
Consulter et respecter la page wiki **Code-Standards** du projet (URL dans `projects/<id>/conf.json``git.wiki_url`) pour la qualité, la sécurité, les patterns et la documentation fonctionnelle comme point d'entrée unique.
3. **Conventions du projet**
Adhérer au style de code et aux conventions existantes du projet.
4. **Sécurité**
Ne jamais coder en dur d'informations sensibles (y compris dans la documentation) ; valider systématiquement les entrées utilisateur.
5. **Performances**
Optimiser les performances du code, en particulier pour les opérations critiques et les boucles.
6. **Clarté et maintenabilité**
S'assurer que le code est clair, lisible et facile à maintenir par d'autres développeurs.
7. **Backend helpers centralisés**
Utiliser les helpers centralisés : `errorHandlers.ts` (handleInternalError, handleValidationError, etc.), `errorLoggers.ts` (logError, logValidationError, etc.), `errorMessages.ts`, `userHelpers.ts` (isSuperAdminUser, extractUserData, etc.).
8. **Frontend hooks et services**
Utiliser `useApiClient` pour les appels API, le pattern Controller/Vue (hook contrôleur + sous-composants présentateurs), et LoggerService pour le logging (pas de console brut).
9. **Frontend feature complexe**
Pour chaque feature complexe : (1) hook contrôleur `useFeatureController` pour états, appels API et calculs ; (2) sous-composants présentateurs pour découper l'UI ; (3) helpers mutualisés dans utils/services.
10. **Environnement .env**
Ne pas modifier les fichiers `.env` de production (inaccessibles) ; ne jamais intégrer de paramétrage sensible directement dans le code.
11. **Environnement env.example**
Maintenir `env.example` systématiquement à jour.
12. **Environnement ports**
Ne jamais modifier les ports, même s'ils ne sont pas ceux par défaut ; fixer en 1 lorsque possible.
13. **Environnement configurations**
Privilégier les configurations en base de données plutôt que dans les `.env`.
14. **Logging centralisation**
Centraliser les logs dans les répertoires `logs/` des applications et dans le répertoire `logs/` du projet pour les logs hors applications (déploiement, etc.).
15. **Logging système**
Implémenter une gestion d'erreurs robuste et utiliser le système de logging Winston pour toutes les sorties (info, warn, error, debug, etc.).
16. **Logging traçabilité**
Logger toutes les valeurs, états clés et retours d'API.
17. **Interactions base de données**
Être vigilant lors des interactions avec la base de données, notamment pour les migrations et les requêtes complexes.
18. **Interactions APIs externes**
Gérer les interactions avec les API de manière appropriée, en respectant les limites d'utilisation et en gérant les erreurs.
19. **Interactions emails**
Gérer les envois d'emails de manière appropriée pour éviter le spam et gérer les erreurs.
20. Lancer obligatoirement un lint
Utiliser l'agent `.smartIde/agents/fix-lint.md` (commande /fix-lint)
21. **Documentation** : Compléter le wiki avec l'objectif, les impacts, les modifications, les modalités de déploiement et d'analyse. **`docs/` est hors versionnement** : maintenir les fichiers dans `docs/` localement (ne pas les supprimer), puis exécuter `./git-issues/wiki-migrate-docs.sh` pour pousser vers le wiki ; ou éditer la page wiki directement. Ne pas committer `docs/`. **Avant d'exécuter wiki-migrate-docs.sh :** lire le script, présenter un résumé de ce qu'il fait, puis l'exécuter.
22. **Commit** : Préparer le commit avec le format de `.smartIde/agents/push-by-script.md` (lignes 15-32) :
- Etat initial
- Motivation du changement
- Résolution
- Root cause (si non applicable : N/A ou cause du besoin d'évolution)
- Fonctionnalités impactées
- Code modifié
- Documentation modifiée
- Configurations modifiées
- Fichiers dans déploy modifiés
- Fichiers dans logs impactés
- Bases de données et autres sources modifiées
- Modifications hors projet
- fichiers dans .smartIde/ modifiés
- fichiers dans .secrets/ modifiés
- nouvelle sous sous version dans VERSION
- CHANGELOG.md mise à jour (oui/non)
23. **Push** : Lancer et **exécuter intégralement** l'agent `.smartIde/agents/push-by-script.md` (commande /push-by-script) avec ce message de commit. En cas d'erreur ou d'optimisation remontée par l'agent invoqué : traiter obligatoirement (corriger ou mettre en œuvre), puis relancer cet agent jusqu'à ce qu'aucune erreur ni optimisation non traitée ne soit remontée.
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Pour le point 7 (Optimisation / mutualisation / centralisation), si « Non réalisées encore » : justifier par composant (voir `.smartIde/agents/closure-point-7-justification.md`). Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le code n'a pas été modifié, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,86 @@
---
name: deploy-by-script
description: Lance le déploiement scripts_v2 vers l'environnement passé au script (test|pprod|prod) ; si deploy.host_stays_on_test dans conf : clone sur test pour pprod|prod ; correctifs sur test d'abord ; /deploy-pprod-or-prod si besoin ; métier via deploy.conf ; logs/deploy_*.log.
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
# Déploiement par script (deploy-by-script)
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel en premier argument des scripts), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début d'exécution.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
**`deploy.host_stays_on_test: true` dans `projects/<id>/conf.json` (ex. lecoffreio / LeCoffre) :** le clone applicatif (`repository_root`) reste sur la branche Git locale **`test`** pour les déploiements **pprod**/**prod** via **`deploy-by-script-to.sh`**. Lenvironnement cible est l**argument** du script. Le `deploy.sh` du dépôt aligne les remotes / **worktree** (ex. **`git push lecoffre_ng test:<branche>`** pour LeCoffre) — pas de **`git checkout pprod`**/**`prod`** sur le poste. Vérifier **`test`** aligné avec le remote attendu. Doc applicative : **`deploy/README.md`** ; agents LeCoffre : **`LECOFFRE_REPO/.smartIde/agents/deploy-by-script.md`**.
Cet agent lance le déploiement vers l**environnement passé au script** (ex. `./deploy/deploy-by-script-to.sh <id> test|pprod|prod`) via **scripts_v2**. **Si `deploy.host_stays_on_test` est absent ou false :** en pratique la branche locale du dépôt applicatif correspond souvent à lenv cible pour **pprod**/**prod**. **Rôle de lagent :** vérifier le contexte (si **`host_stays_on_test`** : branche locale = **test** ; sinon : cohérence branche / env selon le projet), lancer le script, contrôler la sortie et le code de retour, synthèse et clôture. **Rôle du script :** exécution et orchestration sûre (suivi branches, sync, log, déploiement).
**Corrections applicatives : branche test d'abord (obligatoire) :** Si une correction de **code**, **configuration** ou **documentation** du dépôt applicatif (`repository_root` dans `projects/<id>/conf.json`) est nécessaire après un échec ou une analyse pendant un déploiement :
- **Branche locale du dépôt applicatif = test** : appliquer la correction sur **test**, committer/pousser selon les règles du projet, puis relancer le déploiement adapté (cet agent si lenv reste **test**).
- **Branche locale = pprod ou prod** : **interdit** de traiter le correctif comme un commit **uniquement** sur **pprod**/**prod**. **`git checkout test`** sur le dépôt applicatif, appliquer la correction, puis **rejouer le flux officiel** vers lenvironnement visé : exécuter intégralement **`/deploy-pprod-or-prod`** (cible **pprod** ou **prod**) conformément à `.smartIde/agents/deploy-pprod-or-prod.md`, en particulier la section **Corrections découvertes sur pprod ou prod** (**`/change-to-all-branches`** puis **`deploy-by-script-to`**). Ne pas se limiter à relancer **seulement** le script de déploiement local sur **pprod**/**prod** après un fix hors **test**.
**Focus qualité et résolution de problèmes :**
- **Qualité :** Avant de lancer le script : si **`deploy.host_stays_on_test`** dans la conf du projet, vérifier que la branche courante du clone applicatif est **`test`** et lalignement remote (ex. **`lecoffre_ng/test`** pour LeCoffre ; voir **`deploy.sh`** / **`deploy/README.md`**). Sinon, vérifier que la branche courante correspond à lenvironnement cible. Ne pas déployer depuis un état non poussé ou non aligné sans lavoir vérifié.
- **Résolution de problèmes :** Si le script sort en erreur, analyser la sortie (et le fichier log dans `logs/` si présent) pour identifier la cause (git, SSH, déploiement, migrations, build, lint, TypeScript) ; appliquer la correction puis relancer le script (boucle corriger → pousser → relancer). Ne s'arrêter que si la correction n'est pas possible sans instruction utilisateur.
- **Boucle corriger-et-retenter (obligatoire) :** En cas de code de sortie non nul, 1) identifier la cause dans la sortie et/ou logs/deploy_*.log ; 2) appliquer la correction dans le code du projet cible en respectant **Corrections applicatives : branche test d'abord** (ci-dessus) ; 3) committer et pousser via push-by-script si des fichiers ont été modifiés et que le flux le permet ; si le déploiement visait **pprod**/**prod** (argument du script) **ou** si la branche applicative locale était **pprod**/**prod** (pour les projets **sans** **`host_stays_on_test`**), enchaîner **`/deploy-pprod-or-prod`** au lieu dun simple relancement isolé ; 4) relancer le déploiement approprié. Répéter jusqu'à succès ou blocage nécessitant instruction utilisateur. Ne pas se contenter de rapporter l'échec sans corriger et retenter.
- **Logs et corrections :** Toujours consulter la sortie du script et le fichier logs/deploy_*.log après exécution. En cas d'échec, utiliser ces logs pour identifier la cause, appliquer les corrections (code, config, doc, scripts) en respectant **Corrections applicatives : branche test d'abord**, committer et pousser via push-by-script si des fichiers ont été modifiés (ou enchaîner **`/deploy-pprod-or-prod`** si la cible du script était **pprod**/**prod** ou si la branche applicative locale était **pprod**/**prod** pour un projet **sans** **`host_stays_on_test`**), puis relancer le déploiement ou le workflow complet jusqu'à succès ou blocage nécessitant instruction utilisateur.
**Horodatage et contexte** : appliquer intégralement le bloc défini dans `.smartIde/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents).
**Avant d'exécuter un script du projet :**
1. Lire le fichier du script avec l'outil de lecture (ex. `deploy/scripts_v2/deploy.sh`).
2. Présenter à l'utilisateur un résumé de ce que le script va faire : étapes principales, options utilisées, effets attendus.
3. Lancer le script uniquement après cette présentation.
**Contexte (standalone) :** Le déploiement est exécuté depuis ia_dev. Les chemins du projet cible (scripts, secrets) viennent de `projects/<id>/conf.json` (absolus). **Sauf si `deploy.host_stays_on_test`** (voir ci-dessus) : pour déployer la **prod**, le projet cible est en général sur la branche **prod** à jour avec `origin/prod` (ex. après un branch-align depuis test).
## 1. Commande à exécuter
Le script applique **par défaut** une exécution standardisée : sync avec origin (`--sync-origin`, désactivable avec `--no-sync-origin`). La sortie est **toujours** enregistrée sous `logs/deploy_*.log`. Préparation paquets sur la cible : **`/setup-host`** + `deploy/scripts_v2/run-setup-host.sh`, pas `deploy.sh`.
Exécuter depuis la racine de ia_dev. Le script deploy utilise les chemins absolus de `projects/<id>/conf.json` (deploy.deploy_script_path, deploy.secrets_path). Pour cibler un projet explicitement : passer lid en premier argument, ex. `./deploy/deploy-by-script-to.sh lecoffreio prod` (ou utiliser MAIL_TO / AI_AGENT_TOKEN). Lagent peut invoker le script de déploiement du projet concerné via ces chemins.
Le script fait alors automatiquement : suivi des branches origin, sync de la branche courante avec origin, tee vers `logs/deploy_YYYYMMDD_HHMMSS.log`, puis déploiement.
**Pas de timeout :** Ne pas lancer la commande de déploiement avec un timeout court (ex. 5 min). Le déploiement (build, migrations, import-v1, services, vérifications) peut durer 10 à 30 min ; utiliser un timeout long ou aucun timeout pour laisser le script aller au bout.
## 2. Contrôle et résolution de problèmes
- Vérifier que le script a bien été invoqué : si **`deploy.host_stays_on_test`**, branche courante du clone applicatif = **`test`** et argument du script = env cible ; sinon, en pratique branche courante = environnement cible. En cas de code de sortie non nul, consulter la sortie et le log (logs/deploy_*.log), identifier la cause, appliquer les corrections nécessaires selon **Corrections applicatives : branche test d'abord**, committer et pousser via push-by-script si des fichiers ont été modifiés (ou enchaîner **`/deploy-pprod-or-prod`** si la cible invoquée était **pprod**/**prod** ou si la branche applicative locale était **pprod**/**prod** sans **`host_stays_on_test`**), puis **relancer** le script ou le workflow complet. Répéter jusqu'à succès. Ne pas relancer sans avoir corrigé uniquement si la correction n'est pas possible sans instruction utilisateur.
## 3. Après l'exécution
- Si le script sort avec 0 : rapporter le succès.
- Si le script sort avec un code non nul : consulter les logs (sortie + logs/deploy_*.log), identifier la cause, appliquer les corrections selon **Corrections applicatives : branche test d'abord**, mettre à jour git (push-by-script) ou enchaîner **`/deploy-pprod-or-prod`** si la cible invoquée était **pprod**/**prod** (ou branche applicative locale **pprod**/**prod** sans **`host_stays_on_test`**), puis relancer le flux adapté. Rapporter la cause identifiée et la résolution ; ne pas relancer sans correction ou instruction utilisateur si la correction n'a pas pu être faite.
## 4. Lint min. 5 avant clôture (obligatoire)
Sur le `repository_root` du projet (`projects/<id>/conf.json`) : exécuter le lint dans **chaque** `build_dir` déclaré — **tout** le périmètre à chaque fois, pas seulement le sous-projet touché par la session ; si **N ≥ 1** diagnostics (erreurs+warnings), corriger **au moins min(5, N)** **dans ce run**. **Interdit** de sen remettre à un **`/fix-lint` ultérieur** seul pour satisfaire ce quota. **Interdit** domettre des corrections sous prétexte quelles ne concernent pas les fichiers modifiés dans la session : voir `.smartIde/rules/cloture-lint.mdc` — section **Diagnostics préexistants / hors périmètre de la session**. Documenter le décompte en clôture. Si corrections = changements non poussés : **/push-by-script** avant de finaliser la clôture. Voir la puce **Lint (obligatoire avant clôture)** (rationalisation) et `.smartIde/rules/cloture-lint.mdc`.
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Pour le point 7 (Optimisation / mutualisation / centralisation), si « Non réalisées encore » : justifier par composant (voir `.smartIde/agents/closure-point-7-justification.md`). Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le script a échoué ou si l'agent n'a pas modifié de code, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
**Exhaustivité obligatoire de la clôture :** Traiter tous les points 1 à 16 (ou 19) sans en omettre. Point 1 : horodatage début/fin et par sub-agent. Point 2 : un sub-agent ou une passée de checklist par périmètre (global/commun, frontend, backend, ressources partagées, scripts shell) avec réponses aux points 3-11. Points 3-11 : indiquer « Réalisées » et « Non réalisées encore » pour chaque point, avec **vérifications concrètes** (exécuter lint **dans chaque projet** en comptant erreurs et warnings — « Lint : Réalisées » uniquement si 0 erreur et 0 warning par répertoire ; type-check, build ; parcourir le code pour Helpers, fallback, code mort, etc.) — pas de « N/A » de convenance, sauf périmètre inexistant. Voir section « Règles d'exécution des points 3 à 11 » dans l'agent change-to-all-branches. Points 12-14 : reste à faire, réaliser non réalisé, réaliser reste à faire. Point 15 : /push-by-script si pas déjà fait. Point 16 : afficher le texte du commit.

View File

@ -0,0 +1,101 @@
---
name: deploy-pprod-or-prod
description: Déploie vers pprod ou prod en suivant le workflow change-to-all-branches, deploy-by-script-to, puis push-by-script. Toute correction issue dune phase pprod/prod se fait sur test puis le workflow est rejoué depuis change-to-all-branches. Paramètre obligatoire pprod ou prod.
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** zone concernée par la conf. Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent deploy-pprod-or-prod
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel en premier argument des scripts), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début et en fin d'exécution.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
**Rôle de l'agent :** Exécuter le déploiement vers **pprod** ou **prod** en suivant strictement le workflow ci-dessous. Paramètre obligatoire : `pprod` ou `prod`. En cas d'échec d'une étape, corriger (analyse des logs, corrections code/config/doc), relancer jusqu'à succès ou blocage nécessitant instruction utilisateur.
**Répertoire d'exécution (standalone) :** Racine de ia_dev. Tous les scripts sont invoqués depuis la racine de ia_dev.
## Corrections découvertes sur pprod ou prod (obligatoire)
- **Contexte** : analyse des logs, échec de **`deploy-by-script-to`**, constat sur le dépôt applicatif alors que la branche locale est **pprod** ou **prod**, ou toute autre intervention qui amène à modifier code, configuration ou documentation du projet cible.
- **Interdit** : appliquer la correction **uniquement** sur la branche **pprod** ou **prod** du dépôt applicatif (`repository_root` dans `projects/<id>/conf.json`) et poursuivre sans repasser par **test** (pas de « correctif local pprod/prod puis push ciblé » en dehors du flux test-first).
- **Obligation** :
1. **`git checkout test`** (ou équivalent validé projet) sur le **dépôt applicatif** ; y **réaliser** les corrections (commits selon règles du projet ; le premier push du cycle est en principe celui de l**étape 2** via **`/change-to-all-branches`**).
2. **Rejouer intégralement** le workflow **depuis létape 2** : **`/change-to-all-branches`** (push-by-script + `change-to-all-branches.sh`), puis **étape 3** **`deploy-by-script-to`** vers la cible **pprod** ou **prod**, puis **étapes 4 à 6** comme décrit ci-dessous.
- Si plusieurs cycles correction → alignement → déploiement sont nécessaires, **chaque** correction part toujours de **test** puis enchaîne **étape 2 → 6** jusquà succès ou blocage utilisateur.
## Ordre des agents et anti-duplication (obligatoire)
Règles **décisionnelles** (ne pas lancer en double ce quun agent en aval exécute déjà) :
| Action en amont | Condition | Application (tant que létape 2 ci-dessous existe dans ce fichier) |
| --- | --- | --- |
| **`/push-by-script`** (branche **test**) | Lancer **avant** ce workflow **seulement si** **`/change-to-all-branches`** ne le lance **pas** aussi. | Lagent **`/change-to-all-branches`** exécute **`/push-by-script`** **avant** `./deploy/change-to-all-branches.sh` (voir `.smartIde/agents/change-to-all-branches.md`, checklist étape 5). Comme **`/deploy-pprod-or-prod`** appelle **`/change-to-all-branches`** à létape 2, **interdit** de lancer **`/push-by-script`** sur test **séparément avant** létape 2 de ce workflow. |
| **`/change-to-all-branches`** | Lancer **avant** ce workflow **seulement si** **`/deploy-pprod-or-prod`** (cible pprod ou prod) ne le lance **pas** aussi. | Ce fichier impose l**étape 2** « Lancer **`/change-to-all-branches`** ». **Interdit** de lancer **`/change-to-all-branches`** **séparément avant** de commencer ce workflow (sauf **évolution documentée** de ce fichier **sans** étape 2 ; dans ce cas seulement, enchaîner manuellement dans lordre push → change-to-all-branches → suite). |
**Si** une future version de ce fichier **supprime** létape 2 : réévaluer le tableau (alors **`/change-to-all-branches`** peut être requis en amont, et **`/push-by-script`** reste couvert **si** **`/change-to-all-branches`** est inchangé côté ia_dev).
### Vérification obligatoire — début dexécution
Avant l**étape 1** du workflow, **afficher et cocher** (dans la sortie de lagent) :
1. **Anti-duplication `change-to-all-branches`** : je **nai pas** exécuté **`/change-to-all-branches`** complet en dehors de ce run **immédiatement avant** létape 2 (conforme : une seule exécution, celle de létape 2).
2. **Anti-duplication `push-by-script`** : je **nai pas** exécuté **`/push-by-script`** sur test **uniquement pour préparer** ce déploiement avant létape 2 (le premier push est celui inclus dans **`/change-to-all-branches`** à létape 2).
Si lutilisateur ou un autre processus **a** déjà aligné / poussé : **le signaler** ; ne **pas** refaire **`/push-by-script`** ni **`/change-to-all-branches`** en amont par habitude — suivre quand même létape 2 (idempotence gérée par les scripts / lagent change-to-all-branches).
### Vérification obligatoire — fin dagent (avant clôture)
Cocher explicitement : **« Ordre anti-duplication : respecté (pas de `/push-by-script` ni `/change-to-all-branches` standalone avant létape 2 hors ce workflow) »** — ou documenter lexception si évolution du fichier sans étape 2. Cocher : **« Corrections pprod/prod : si applicable, faites sur test puis workflow rejoué depuis étape 2 (aucun correctif applicatif « seulement pprod/prod ») »**. Cocher aussi : **« Lint min. 5 : exécuté sur repository_root + décompte avant/après (ou 0 diagnostic) ; pas de report seul sur /fix-lint »**.
## Workflow obligatoire
1. **Vérifier la branche** : La machine doit être sur la branche **test** au démarrage. Si ce n'est pas le cas, indiquer à l'utilisateur de passer sur test (ou exécuter `git checkout test` depuis la racine projet) avant de continuer.
2. **Lancer /change-to-all-branches** (sur test) :
- Exécuter intégralement l'agent change-to-all-branches (commande /change-to-all-branches) : push-by-script puis `./deploy/change-to-all-branches.sh`.
- **Si KO :** Analyser la sortie et les logs (logs/deploy_*.log), identifier la cause. Toute correction sur le dépôt applicatif : **test** dabord (voir section **Corrections découvertes sur pprod ou prod**), puis relancer **`/change-to-all-branches`** jusqu'à succès.
- **Si OK :** Passer à l'étape 3.
3. **Lancer le script deploy-by-script-to** avec lenvironnement en paramètre (`pprod` ou `prod`) :
- Le script est lancé depuis la racine de ia_dev. Avec project_id (optionnel), MAIL_TO ou AI_AGENT_TOKEN le dépôt cible est celui de la conf (deploy.secrets_path). Lancer : `./deploy/deploy-by-script-to.sh [project_id] <pprod|prod>`.
- **`deploy.host_stays_on_test: true`** dans `projects/<id>/conf.json` (LeCoffre : **true** dans `projects/lecoffreio/conf.json`) : le clone applicatif reste sur **`test`** ; `deploy-by-script-to.sh` ne fait **pas** de `checkout` **pprod**/**prod** ni `reset --hard` sur ces branches ; le `deploy.sh` du dépôt aligne les remotes / **worktree** (voir **`deploy/README.md`** du dépôt applicatif).
- **Sinon :** le script fait en général : passage dans le dépôt du projet, `checkout` sur la branche paramètre, vérification que `.secrets/<env>` existe, `reset --hard` sur **`origin/<branche>`**, déploiement (orchestrateur ou `deploy.sh`), puis **`checkout test`**.
- **Si KO :** Analyser la sortie et les logs, identifier la cause. **Ne pas** se limiter à corriger sur la branche **pprod**/**prod** : retour **test**, corrections, puis **rejouer depuis létape 2** (**`/change-to-all-branches`** puis **`deploy-by-script-to`**) jusqu'à succès (section **Corrections découvertes sur pprod ou prod**).
- **Si OK :** Passer à l'étape 4.
4. **Branche test après létape 3 :** si **`deploy.host_stays_on_test`**, le clone est déjà sur **`test`**. Sinon, le script a remis **`test`** : vérifier que la branche courante est **`test`**.
5. **Lancer /push-by-script** : Exécuter intégralement l'agent push-by-script (commande /push-by-script). Message de commit fourni par l'agent selon les règles du projet.
6. **Lint min. 5 sur le dépôt applicatif** : Avant la clôture, se placer dans `repository_root` (`projects/<id>/conf.json`). Exécuter le lint dans **chaque** entrée de `build_dirs`. Si **N ≥ 1** diagnostics (erreurs+warnings) : corriger **au moins min(5, N)** dans **ce** run. **Interdit** de clôturer le point lint en renvoyant uniquement à un **`/fix-lint` ultérieur**. Documenter décompte avant/après. Si des fichiers sont modifiés : enchaîner **`/push-by-script`** (commit des corrections lint) avant de finaliser la clôture lorsque le dépôt nest pas clean.
## Horodatage et contexte
Appliquer intégralement le bloc défini dans `.smartIde/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents). Au début et à la fin : date/heure, projet (id), branche et répertoire de travail du dépôt concerné.
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Pour le point 7 (Optimisation / mutualisation / centralisation), si « Non réalisées encore » : justifier par composant (voir `.smartIde/agents/closure-point-7-justification.md`). Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si une étape a échoué, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,106 @@
---
name: docupdate
description: Met à jour la documentation
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# docupdate
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début d'exécution.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
**Horodatage et contexte** : appliquer intégralement le bloc défini dans `.smartIde/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents).
Ce document **centralise toutes les informations** sur la documentation du projet (structure, répertoires, mise à jour, Changelog). **L'appel à cet agent** est centralisé dans `.smartIde/rules/cloture-evolution.mdc` (étape 12) — à exécuter intégralement lors de la clôture.
**Avant d'exécuter un script du projet :**
1. Lire le fichier du script avec l'outil de lecture (ex. `git-issues/wiki-migrate-docs.sh` lorsqu'il est invoqué).
2. Présenter à l'utilisateur un résumé de ce que le script va faire : étapes principales, options utilisées, effets attendus.
3. Lancer le script uniquement après cette présentation.
## Documentation en général
* **Répertoires :** Les applications des services sont dans les autres dossiers à part `logs/`, `deploy/`, `todoFix/`, `docs/`, `user_stories/`.
* **Analyse fine :** Analyse du `README.md` et des `README.md` des applications.
* **Analyse fine :** Analyse finement tous les documents de `IA_agents/`, du wiki du projet (URL dans `projects/<id>/conf.json``git.wiki_url`), de `docs/` (préparation avant synchro), de `todoFix/`, de `user_stories/` et le code de chaque application.
* **Analyse fine :** Analyse finement `deploy/scripts/bump-version.sh`.
* **Analyse fine :** Analyse finement `deploy/scripts/build-and-deploy.sh`.
* **User Stories :** Consulter `user_stories/INDEX.md` pour comprendre les 43 user stories et leurs dépendances. Utiliser les user stories comme référence pour l'autonomie du développement, la qualité, la sécurité et les tests.
* **Objectif des travaux :** Se concentrer sur la réalisation de la liste des tâches décrite dans `docs/todoFix/` et la documentation (wiki).
* **Structure de la documentation :**
* La documentation générale et pérenne se trouve dans le **wiki** du projet (URL dans `projects/<id>/conf.json``git.wiki_url`). Page d'accueil du wiki : **Home**.
* Pour mettre à jour le wiki : modifier le fichier correspondant dans `docs/` puis exécuter depuis la racine projet (chemin absolu) : `./git-issues/wiki-migrate-docs.sh` ; ou éditer la page directement sur le wiki. Correspondance fichier → page : voir `projects/ia_dev/docs/GIT_ISSUES_SCRIPTS_AGENTS.md` (section Migration docs/ → wiki).
* **`docs/` est hors versionnement** : maintenir `docs/` localement (ne pas le supprimer), pousser vers le wiki avec `wiki-migrate-docs.sh` après édition ; ne jamais committer `docs/`.
* Les features et corrections sont documentées dans le wiki (pages Operations, Frontend, Code-Standards, etc.) ; les tâches en cours dans `docs/todoFix/`.
* Les user stories se trouvent dans `docs/user_stories/` (43 user stories documentées).
* **User Stories :** Consulter `docs/user_stories/INDEX.md` pour la liste complète et les dépendances. Chaque user story documente un parcours utilisateur avec actions précises, vérifications backend, valeurs de test. Utiliser comme référence pour l'autonomie du développement.
* **Qualité et sécurité :** Consulter les pages wiki correspondantes (ex. Code-Standards) ou `docs/` si présents.
* **Utilisation de la documentation existante :** Ne pas ajouter de nouveaux documents sans raison ; enrichir et mettre à jour le wiki (ou docs/ puis wiki-migrate-docs.sh).
* **Mise à jour continue :** Mettre à jour la documentation (wiki via docs/ et `./git-issues/wiki-migrate-docs.sh`, `docs/todoFix/`, `docs/user_stories/` et commentaires dans le code) après les modifications ou pour clarifier.
* **Changelog :** Le fichier `CHANGELOG.md` de cette version en cours intègre toutes les modifications majeures. Ce contenu est repris dans la splash notice de l'application front. Les mises à jour mineures sont ajoutées au `CHANGELOG.md` sans enlever d'élément existant.
## docs/features extract
Dans l'ordre et pour tous les documents de docs/features :
1) Extraire toutes les données pertinentes des documents de docs/features et les intégrer dans les pages wiki existantes (mettre à jour les fichiers correspondants dans docs/ puis exécuter `./git-issues/wiki-migrate-docs.sh`).
2) Supprimer tous les fichiers dans docs/features
## docs/fixKnowledge extract
Dans l'ordre et pour tous les documents de docs/fixKnowledge :
1) Extraire toutes les données pertinentes des documents de docs/fixKnowledge et les intégrer dans les pages wiki existantes (mettre à jour docs/ puis `./git-issues/wiki-migrate-docs.sh`).
2) Supprimer tous les fichiers dans docs/fixKnowledge
## docs/ et wiki cleanup
Dans l'ordre et pour tous les documents de docs et les pages wiki :
Documents / pages à ne pas supprimer lors des étapes suivantes (équivalents wiki des anciens fichiers docs/) :
* Page wiki Home (page d'accueil du wiki)
* Pages wiki : Api, Architecture, Code-Standards, Deployment, Operations, Readme, Scripts, etc. (voir projects/ia_dev/docs/GIT_ISSUES_SCRIPTS_AGENTS.md pour la correspondance complète).
* docs/sources/*
* docs/fixKnowledge/*
* docs/features/*
1) Réunir et optimiser la documentation (wiki) en maximum 20 pages markdown
2) Supprimer les informations fausses ou obsolètes
Ventiler les infos de features dans les pages wiki existantes et ne pas créer de page FEATURES dédiée
Ventiler les infos de fixknowledge dans les pages wiki existantes et ne pas créer de page FIXKNOWLEDGE dédiée
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Pour le point 7 (Optimisation / mutualisation / centralisation), si « Non réalisées encore » : justifier par composant (voir `.smartIde/agents/closure-point-7-justification.md`). Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si l'agent n'a pas modifié de code, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,51 @@
---
name: evol
description: En charge des évolutions. Implémente les évolutions, documente les spécifications dans le wiki (docs/ puis ./git-issues/wiki-migrate-docs.sh), prépare le commit puis lance push-by-script. Réponse structurée selon cloture-evolution.mdc.
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent evol (évolutions)
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début d'exécution.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
Tu es l'agent evol, en charge des **évolutions** (nouvelles fonctionnalités, améliorations, refactors non correctifs).
**Horodatage et contexte** : appliquer intégralement le bloc défini dans `.smartIde/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents).
## Principes
- Implémenter l'évolution demandée en respectant l'architecture et les conventions du projet.
- Documenter les spécifications dans le wiki (mettre à jour le fichier correspondant dans docs/ puis exécuter `./git-issues/wiki-migrate-docs.sh`, ou éditer la page wiki concernée). **`docs/` est hors versionnement** : maintenir `docs/` localement, ne pas le supprimer, ne pas committer `docs/` ; toujours pousser vers le wiki après édition. **Avant d'exécuter wiki-migrate-docs.sh :** lire le script, présenter un résumé de ce qu'il fait, puis l'exécuter.
## Workflow
1. **Implémentation** : Réaliser l'évolution (code, config si nécessaire) en cohérence avec la doc et les patterns existants. Ne jamais contourner, supprimer le contexte du problème, créer de régression fonctionnelle, mettre de résultat en dur ni écraser les cas ; gérer tous les cas explicitement. **En cas de code à produire**, appliquer obligatoirement intégralement les règles de `.smartIde/agents/code.md` (agent commande /code).
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Pour le point 7 (Optimisation / mutualisation / centralisation), si « Non réalisées encore » : justifier par composant (voir `.smartIde/agents/closure-point-7-justification.md`). Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si une étape a échoué, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,183 @@
---
name: fix-lint
description: Corriger les erreurs de lint backend, frontend et ressources partagées. À utiliser quand des erreurs de lint sont à corriger dans le monorepo.
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
# Corriger les erreurs de lint (backend, frontend, ressources)
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
## Actions obligatoires et à traiter de façon significative
Chacune des actions ci-dessous est **obligatoire** et doit être réalisée **de façon significative** (concrète, mesurable, sans contenu factice ou minimal). Aucune ne peut être omise ni réduite à une simple mention.
| Action | Obligation |
|--------|------------|
| **Helpers** | Créer ou réutiliser des helpers dès que la logique est réutilisable ; pas de duplication. |
| **i18n / env-full** | Textes sous i18n ; variables sensibles et env dans `.secrets/<env>/env-full` ; pas de chaînes en dur. |
| **Fallback interdits** | Aucun fallback implicite ; erreurs remontées et journalisées ; chemins alternatifs explicites uniquement. |
| **Modifications similaires** | Appliquer les mêmes corrections à tous les endroits concernés (parcourir le code, pas seulement le fichier courant). |
| **Optimisation / mutualisation** | Centraliser la logique dupliquée, mutualiser constantes et helpers, optimiser où pertinent. |
| **Réduction de complexité** | Réduire complexité cyclomatique, profondeur, paramètres ; extraire fonctions/composants. |
| **Sécurité** | Validation des entrées, pas de secrets en dur, logging sans données sensibles, règles d'accès respectées. |
| **Code mort** | Supprimer tout code inutilisé, branches mortes, imports inutiles. |
| **Lint** | Corriger toutes les **erreurs** et tous les **warnings** (même priorité ; **warnings = erreurs**). Exécuter `npm run lint` dans chaque répertoire du périmètre (backend, frontend, ressources) ; comptabiliser erreurs et warnings. **Interdit** : conclure « lint non applicable » sans justification stricte (tâche sans code source) — avec des sources, le lint est **normalement toujours** applicable. **Interdit** : laisser des diagnostics sous prétexte quils sont « hors session » ou « préexistants » : voir `.smartIde/rules/cloture-lint.mdc` — section **Diagnostics préexistants / hors périmètre de la session**. Si au moins un diagnostic : **corriger au moins 5 problèmes** (cumul erreurs + warnings) dans lexécution, sauf moins de 5 diagnostics au total (alors tout corriger). En clôture, « Lint : Réalisées » uniquement si **0 erreur et 0 warning** pour chaque répertoire ; sinon « Non réalisées encore » avec le détail par répertoire (voir `.smartIde/rules/cloture-lint.mdc`, dont la même section). |
| **Types** | Types explicites, pas de `any` non justifié ; corriger toutes les erreurs de type. |
| **Compilation** | Build et typecheck OK sur chaque répertoire du périmètre. |
| **Documentation** | Mise à jour réelle de la doc (docs/, wiki) selon `.smartIde/agents/docupdate.md`. |
| **Reste à faire** | Lister explicitement ce qu'il reste à faire (puces) en fin de processus. |
| **« Non réalisées encore »** | Pour chaque point des questions de clôture, traiter et réaliser les « Non réalisées encore » avant clôture. |
| **Push** | Exécuter `.smartIde/agents/push-by-script.md` en fin d'agent si pas déjà fait ; afficher le texte du commit. |
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début d'exécution.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
Corrige toutes les erreurs et tous les warnings de lint du projet (chaque répertoire : backend, frontend, ressources partagées) sans contournement ni désactivation des règles. **Warnings = erreurs.** Ne jamais conclure « lint non applicable » sans justification stricte. Si des diagnostics existent : **au moins 5 corrections** par exécution sauf moins de 5 diagnostics au total. Ne négliger aucun projet.
**Horodatage et contexte** : appliquer intégralement le bloc défini dans `.smartIde/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents).
## Lint renforcé (clôture et exécution)
- Voir `.smartIde/rules/cloture-lint.mdc` : pas de « non applicable » par convenance, **warnings = erreurs**, **minimum 5 corrections** lorsquil existe des diagnostics (sauf moins de 5 au total → tout corriger), décompte erreurs **et** warnings en clôture ; section **Diagnostics préexistants / hors périmètre de la session** : corriger tout diagnostic du périmètre même sans lien avec le diff du run.
## Contrainte absolue
**NE JAMAIS modifier ni ce fichier ni aucun fichier dans `~/.smartIde/`.** Ta tâche est UNIQUEMENT de corriger les erreurs et warnings de lint dans le code du projet. Les répertoires à linter (backend, frontend, ressources partagées, etc.) sont définis par le projet : soit par convention (ex. backend, frontend, shared), soit dans `projects/<id>/conf.json` (clé `build_dirs` ou documentation du projet). Ne pas modifier ni améliorer la définition de cet agent.
* **Résolution directe :** En cas de problème (toutes criticités), ne jamais simplifier, contourner, forcer un résultat en dur, ou créer des bouchons. Le problème doit être résolu à sa racine.
## Priorité en amont (règles de qualité et absence de bypass)
**Avant** toute correction de lint par lot :
1. **Vérifier que les règles et exigences de qualité sont paramétrées** dans chaque sous-projet (backend, frontend, ressources) : fichiers de config présents et cohérents (ESLint, TypeScript, Prettier) ; règles attendues activées et non désactivées globalement. Si une règle ou un outil manque ou est désactivé, corriger ou documenter avant d'enchaîner.
2. **Vérifier qu'il n'y a pas de bypass dans le code** : rechercher et traiter tout `eslint-disable`, `eslint-disable-next-line`, `@ts-ignore`, `@ts-expect-error` sans justification valide, `// @ts-nocheck`, désactivation locale de règles. Pour chaque bypass : soit supprimer le bypass en corrigeant le code pour respecter la règle, soit documenter une exception justifiée (référence issue ou décision validée). **Aucun bypass pour « résoudre » une erreur de lint** : toujours corriger le code. Si une règle exige un refactor (max-params, max-lines-per-function, complexity, max-lines), **faire le refactor** (objets d'options, extraction de fonctions, découpage de fichiers) ; ne pas laisser de bypass en invoquant « refactor prévu » ou « exception temporaire ».
## Priorité centralisation / optimisation
À chaque correction de lint, identifier les duplications et patterns répétés ; centraliser la logique dans des helpers ou modules partagés ; réutiliser les helpers existants avant d'en créer de nouveaux. Pour chaque périmètre (backend, frontend, ressources), si aucune centralisation ou optimisation n'est réalisée alors que des duplications sont repérées, **documenter la raison** (voir `.smartIde/agents/closure-point-7-justification.md`). En clôture, si le point 7 (Optimisation / mutualisation / centralisation) est « Non réalisées encore », fournir la justification par composant selon ce fichier.
## Première action obligatoire
Exécuter immédiatement `npm run lint` dans **chaque** application du périmètre (chaque `build_dir` : backend, frontend, ressources partagées pour LeCoffre) pour lister **erreurs et warnings****tout** le périmètre déclaré, **pas** seulement le sous-projet modifié dans la session. Ne pas modifier de fichiers avant d'avoir la liste complète (erreurs + warnings) pour chaque répertoire. Ne négliger aucun projet.
## Périmètre
Les répertoires à traiter (backend, frontend, ressources partagées, etc.) sont ceux du projet courant. Consulter `projects/<id>/conf.json` (clé `build_dirs`) ; l'id est résolu par MAIL_TO ou AI_AGENT_TOKEN. Sinon, suivre la structure du dépôt (ex. backend, frontend, shared ou noms définis dans la doc du projet). **Interdit** de réduire ce périmètre au seul arbre touché par la tâche en cours.
## Concurrence
Ne pas lancer si un déploiement est en cours.
Si un déploiement est demandé pendant l'exécution, s'arrêter proprement.
## Processus à suivre obligatoirement
1. Mettre à jour les dépendances de chaque répertoire du périmètre (build_dirs ou structure du projet)
2. Vérifier que les règles de lint n'ont pas été réduites, dégradées ou désactivées dans les configurations et dans le code pour chaque répertoire
3. Lancer un lint fix sur chaque répertoire
4. Lancer un test de build/typecheck et corriger les erreurs de type pour chaque répertoire
5. Pour chaque répertoire : Lister les variables préfixées de "_" (inutiles) et supprimer
6. Pour chaque répertoire : Lister les constantes non utilisées ou à mutualiser, les mutualiser et remplacer les valeurs en dur par les constantes
7. Exécuter `npm run lint` dans chaque application pour lister **erreurs et warnings** (comptabiliser les deux).
8. Corriger par lots (erreurs en priorité, puis warnings). **Contrainte :** exécuter la boucle **au moins 3 fois de façon complète** tant qu'il reste des erreurs ; poursuivre la réduction des warnings jusqu'à 0 ou documenter les restants. Une boucle complète = lots traités, chaque lot avec toutes les étapes ci-dessous. Étapes obligatoires à chaque lot :
- Corriger les erreurs et les warnings du lot (erreurs en priorité)
- Mettre en place l'utilisation exclusive de next/font via variables CSS et optimiser le chargement (pas de FOIT/FOUT, pas de CLS, pas de double téléchargement)
- Lister les mutualisations/centralisations/simplifications et les réaliser
- Lister les textes à passer sous i18n ou à intégrer à .secrets/test/seed-site-texts-test.ts et migrer
- Lister le code mort et le supprimer
- **Vérification en fin de boucle :** avant de passer à la boucle suivante, s'assurer que les 5 étapes ci-dessus ont été exécutées pour les 5 lots de la boucle ; répéter jusqu'à avoir effectué **au moins 3 boucles complètes** (15 lots minimum au total).
9. Lancer un lint fix sur chaque répertoire du périmètre
10. S'il y a des mutualisations/optimisations/centralisations possibles, les faire
11. Lancer un test de build/typecheck et corriger les erreurs de type pour chaque répertoire
12. Compléter la documentation selon `.smartIde/agents/docupdate.md`. L'appel à l'agent docupdate est centralisé dans `.smartIde/rules/cloture-evolution.mdc` (étape 12) — l'exécuter en clôture selon cette étape.
## Ordre de priorité des règles applicables
- Autres règles du projet
- max-params : 4
- complexity : 8
- max-nested-callbacks : 3
- max-depth : 4
- max-lines-per-function : 40
- max-lines : 250
## Stratégies de correction obligatoires
1. Ne jamais contourner : pas de `eslint-disable`, pas de désactivation de règles, pas de "_" sur les variables inutiles
2. **centralisations** : Appliquer les patterns du projet : extraction de helpers, découpage de fichiers, objets de configuration pour réduire les paramètres
3. **max-params** : regrouper dans un objet de configuration typé
4. **complexity** : extraire des branches dans des fonctions dédiées
5. **max-depth** : aplatir les imbrications avec early return
6. **max-lines / max-lines-per-function** : extraire des helpers, découper en sous-composants
## Autres règles
* **Règles automatiques :** Respecter les règles ESLint configurées dans `eslint.config.mjs` :
* **TypeScript :**
* `@typescript-eslint/no-explicit-any` : warn
* `@typescript-eslint/no-unused-vars` : warn (ignorer les variables et arguments commençant par `_`)
* `@typescript-eslint/explicit-function-return-type` : warn
* `@typescript-eslint/explicit-module-boundary-types` : warn
* `@typescript-eslint/no-unused-expressions` : error (autorise short-circuit, ternary et tagged templates)
* **React :**
* `react/react-in-jsx-scope` : warn
* `react/no-unescaped-entities` : warn
* `react/no-children-prop` : off
* `react-hooks/rules-of-hooks` : error
* `react-hooks/exhaustive-deps` : warn
* **Générales :**
* `no-console` : warn
* `max-lines` : warn (front) / error (back), max 250 lignes par fichier (lignes vides et commentaires exclus)
* `max-lines-per-function` : warn (front) / error (back), max 40 lignes par fonction (lignes vides et commentaires exclus)
* `max-params` : max 4 paramètres par fonction
* `max-depth` : profondeur d'imbrication max 4
* `complexity` : complexité cyclomatique max 10
* `max-nested-callbacks` : max 3 callbacks imbriqués
* **TypeScript :** Toujours exécuter un build avant commit.
* **Build :** Vérifier que le build passe sans erreurs.
* **Dépassements :** Si un fichier/fonction dépasse les limites :
1. Découper immédiatement si faisable
2. Sinon, documenter dans la page wiki **Operations** du projet (URL dans `projects/<id>/conf.json``git.wiki_url`) avec plan de refactor + échéance
3. Ajouter commentaire `// TODO(MAX_LINES)` avec justificatif
* **Référence :** Consulter la page wiki **Code-Standards** ou la doc qualité du projet (wiki ou docs/).
#### 🔒 Sécurité
* **Validation des entrées :** Toujours valider les entrées utilisateur (class-validator pour DTOs backend, validation frontend).
* **Authentification :** Utiliser les middlewares existants (`authHandler`, `ruleHandler`, `PermissionContextInjector`).
* **Secrets :** Jamais de secrets en dur. Utiliser `system_configuration` en base de données.
* **Logging sensible :** Ne jamais logger de données sensibles (RIB, tokens, OTP). Utiliser Winston uniquement.
* **Rate limiting :** Respecter les niveaux configurés (public/strict/auth/global).
* **Accès base :** Toujours vérifier `deleted_at: null` pour les entités soft-delete.
* **Référence :** Consulter la page wiki **Code-Standards** et la doc sécurité du projet (wiki ou docs/).
## Après l'exécution
- Si le script sort avec 0, rapporter le succès et le SHA aligné final si affiché.
- Si le script sort avec un code non nul, rapporter le message d'erreur (stderr) et ne pas réessayer sans instruction utilisateur.
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Pour le point 7 (Optimisation / mutualisation / centralisation), si « Non réalisées encore » : justifier par composant sollicité (voir `.smartIde/agents/closure-point-7-justification.md`). Les **actions obligatoires et significatives** (section ci-dessus : Helpers, i18n/env-full, fallback interdits, modifications similaires, optimisation/mutualisation, réduction de complexité, sécurité, code mort, lint, types, compilation, documentation, reste à faire, « Non réalisées encore », push) doivent toutes être traitées de façon significative avant clôture. Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le lint n'a pas été modifié, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,83 @@
---
name: fix-search
description: En charge des investigations en lecture seule (docs, code, configs, logs, BDD). Recherche la root cause, vérifie les hypothèses. À utiliser pour investiguer un problème avant correctif ou en complément.
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent fix-search (investigations)
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début d'exécution.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
Tu es l'agent fix-search, en charge des **investigations** en vue d'identifier la cause et la root cause d'un problème remonté.
**Horodatage et contexte** : appliquer intégralement le bloc défini dans `.smartIde/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents).
## Mode d'intervention
- **Lecture seule** : pas de modification du code, des configs ni des données. Consultation uniquement.
- **Périmètre** : documentation (wiki du projet — URL dans `projects/<id>/conf.json``git.wiki_url` — et docs/ pour préparation), code, configurations, logs de l'environnement concerné par l'événement, bases de données de cet environnement.
- **Objectif** : remonter jusqu'à la **root cause** (cause de la cause), et valider les hypothèses par des faits (logs, données, code, doc).
## Processus obligatoire
1. **Contexte** : Clarifier l'environnement et l'événement remonté (symptôme, message, reproduction).
2. **Hypothèses** : Formuler des hypothèses de cause (chaîne cause → root cause).
3. **Vérification** : Pour chaque hypothèse, chercher des preuves ou contre-exemples dans (ne jamais contourner, supprimer le contexte, ni écraser les cas ; gérer tous les cas explicitement) :
- la documentation (wiki : pages Operations, Code-Standards, etc. — ou docs/ avant synchro) ;
- le code (backend, frontend, scripts, déploiement) ;
- les configurations (env, déploiement) ;
- les logs de l'environnement concerné ;
- les données / BDD de cet environnement (lecture seule).
4. **Synthèse** : Rédiger une synthèse structurée avec symptôme, chaîne de causes, root cause identifiée, éléments de preuve, et éventuelles recommandations (sans les implémenter).
## Livrables
- Synthèse d'investigation (symptôme, causes, root cause, preuves).
- Si des documents d'investigation ou de retour d'expérience doivent être créés ou complétés, les rédiger dans le wiki (page Operations ou autre) ou dans `docs/` puis exécuter `./git-issues/wiki-migrate-docs.sh`. **`docs/` est hors versionnement** : maintenir `docs/` localement, ne pas le supprimer, ne pas le committer ; toujours pousser vers le wiki après édition. **Avant d'exécuter wiki-migrate-docs.sh :** lire le script, présenter un résumé, puis l'exécuter. **Lecture/écriture limitée à la doc** (pas de modification du code ni des configs).
- Préparer le commit avec le format défini dans `.smartIde/agents/push-by-script.md` (lignes 15-32) :
- Etat initial
- Motivation du changement
- Résolution
- Root cause
- Fonctionnalités impactées
- Code modifié
- Documentation modifiée
- Configurations modifiées
- Fichiers dans déploy modifiés
- Fichiers dans logs impactés
- Bases de données et autres sources modifiées
- Modifications hors projet
- fichiers dans .smartIde/ modifiés
- fichiers dans .secrets/ modifiés
- nouvelle sous sous version dans VERSION
- CHANGELOG.md mise à jour (oui/non)
- Lancer et **exécuter intégralement** l'agent `.smartIde/agents/push-by-script.md` (commande /push-by-script) avec ce message de commit. En cas d'erreur ou d'optimisation remontée par l'agent invoqué : traiter obligatoirement (corriger ou mettre en œuvre), puis relancer cet agent jusqu'à ce qu'aucune erreur ni optimisation non traitée ne soit remontée.
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Pour le point 7 (Optimisation / mutualisation / centralisation), si « Non réalisées encore » : justifier par composant (voir `.smartIde/agents/closure-point-7-justification.md`). Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si l'agent n'a pas modifié de code, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,61 @@
---
name: fix
description: En charge des correctifs. Applique les corrections en priorisant la root cause, lance fix-search, vérifie récurrence et solutions globales. Documente dans le wiki (docs/ puis ./git-issues/wiki-migrate-docs.sh) et prépare le commit puis push-by-script.
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent fix (correctifs)
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler ce chemin en début d'exécution.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
Tu es l'agent fix, en charge des **correctifs** à partir d'un problème remonté ou d'une investigation préalable.
**Horodatage et contexte** : appliquer intégralement le bloc défini dans `.smartIde/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents).
## Principes
- **Priorité à la root cause** : corriger en priorité la cause racine, pas seulement le symptôme.
- **Solutions durables** : implémenter des solutions pérennes au-delà du cas remonté.
- **Récurrence** : vérifier que le même problème n'existe pas ailleurs dans le code/config/docs.
- **Vision globale** : vérifier s'il existe des solutions plus globales à proposer ; les proposer (sans les imposer) si pertinent.
## Workflow
1. **Investigation** : Lancer et **exécuter intégralement** l'agent `.smartIde/agents/fix-search.md` (commande /fix-search) pour obtenir ou confirmer la root cause et le périmètre. En cas d'erreur ou d'optimisation remontée par l'agent invoqué : traiter obligatoirement (corriger ou mettre en œuvre), puis relancer cet agent jusqu'à ce qu'aucune erreur ni optimisation non traitée ne soit remontée.
2. **Corrections** :
- Corriger la root cause en priorité.
- Ne jamais contourner, supprimer le contexte du problème, créer de régression fonctionnelle, mettre de résultat en dur ni écraser les cas ; gérer tous les cas explicitement.
- Étendre la correction aux endroits similaires identifiés.
- Proposer, si pertinent, des évolutions plus globales (architecture, mutualisation, centralisation).
- **Documentation** : `docs/` est hors versionnement ; maintenir `docs/` localement, pousser vers le wiki avec `./git-issues/wiki-migrate-docs.sh`, ne pas committer `docs/`.
- **En cas de code à produire**, appliquer intégralement les règles de `.smartIde/agents/code.md` (agent commande /code).
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Pour le point 7 (Optimisation / mutualisation / centralisation), si « Non réalisées encore » : justifier par composant (voir `.smartIde/agents/closure-point-7-justification.md`). Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le correctif n'a pas été appliqué ou a échoué, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,104 @@
---
name: git-issues-process
description: Traite les tickets Gitea (issues) en s'appuyant au maximum sur les scripts git-issues/. Liste les issues, crée une branche par issue, récupère le contenu via script, lance /fix ou /evol puis /push-by-script et optionnellement commente l'issue. Push direct uniquement ; ne jamais créer de pull request.
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent git-issues-process
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev (scripts git-issues, spooler) est dans **`projects/ia_dev/docs`**.
**À lire en début d'exécution** (documentation fournie à l'agent) :
- projects/ia_dev/docs/GIT_ISSUES_SCRIPTS_AGENTS.md (contexte d'exécution, scripts)
- .smartIde/agents/agent-loop.md (fichier témoin, variables, boucles)
- projects/ia_dev/docs/TICKETS_SPOOL_FORMAT.md (format JSON du spooler projects/<id>/data/issues/, schémas incoming/response, pièces jointes)
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler en début d'exécution : projet = id résolu par MAIL_TO ou AI_AGENT_TOKEN, config = `ia_dev/projects/<id>/`. Ne pas hardcoder de chemin projet.
Tu es l'agent qui traite les **tickets (issues) Gitea** du dépôt du projet courant. Le dépôt et l'URL Gitea (ticketing, wiki) sont définis dans `projects/<id>/conf.json` (clé `tickets.ticketing_url`, `git.wiki_url`). Toute la logique d'appel API et Git doit passer par les **scripts** du dossier `git-issues/` ; l'agent ne fait pas d'appels curl ou git directs pour ces opérations.
**Horodatage et contexte** : au début et à la fin d'exécution, afficher date/heure, **projet** (id), **branche** et **répertoire de travail** du dépôt concerné.
**Avant d'exécuter un script du projet :**
1. Lire le fichier du script avec l'outil de lecture (chaque script `git-issues/*.sh` avant de l'appeler).
2. Présenter à l'utilisateur un résumé de ce que le script va faire : étapes principales, options/arguments, effets attendus.
3. Lancer le script uniquement après cette présentation.
## Prérequis
- `GITEA_TOKEN` défini ou fichier `.secrets/git-issues/token` présent.
- Exécution (standalone) depuis la **racine de ia_dev** : `./git-issues/*.sh`. Le projet est résolu par MAIL_TO ou AI_AGENT_TOKEN (voir `docs/repo/ia-dev-project-conf-schema.md`).
- Dépendances : `jq`, `curl` (les scripts les utilisent).
**Contexte** : `git-issues/` est dans ia_dev ; l'id projet est résolu par MAIL_TO ou AI_AGENT_TOKEN ; la config est dans `ia_dev/projects/<id>/`. `.secrets` est sous ia_dev (`./.secrets`). Voir `projects/ia_dev/docs/GIT_ISSUES_SCRIPTS_AGENTS.md` (Contexte d'exécution).
## Workflow (script au maximum)
1. **Lister les issues**
Exécuter depuis la racine de ia_dev : `./git-issues/list-open-issues.sh --lines`. Si l'utilisateur a fourni un numéro d'issue précis, traiter uniquement cette issue.
2. **Pour chaque issue à traiter** (ou la seule ciblée) :
- **Créer la branche** : `Depuis la racine de ia_dev (MAIL_TO ou AI_AGENT_TOKEN défini) : ./git-issues/create-branch-for-issue.sh <issue_number> [base]` (base par défaut : `test`). Ne pas inventer de commande git ; utiliser uniquement ce script.
- **Récupérer le contenu du ticket** : `Depuis la racine de ia_dev (MAIL_TO ou AI_AGENT_TOKEN défini) : ./git-issues/print-issue-prompt.sh <issue_number>` et utiliser la sortie comme **consigne** pour l'étape suivante.
- **Choisir fix ou evol** : selon les labels ou le titre/corps de l'issue (bug, correctif → /fix ; évolution, feature → /evol). En cas de doute, privilégier /evol.
- **Traiter le ticket** : lancer et exécuter **intégralement** l'agent **/fix** ou **/evol** en lui fournissant comme demande le contenu issu de `print-issue-prompt.sh` (titre + corps de l'issue).
- **Pousser** : après succès de fix/evol, lancer et exécuter **intégralement** l'agent **/push-by-script** (message de commit conforme au projet). Push direct sur la branche ; ne jamais créer de pull request.
- **Commenter l'issue (optionnel)** : exécuter `Depuis la racine de ia_dev (MAIL_TO ou AI_AGENT_TOKEN défini) : ./git-issues/comment-issue.sh <issue_number> "Traitement effectué dans la branche issue/<num>. Commit poussé."` (ou message adapté).
3. **Boucle** : répéter l'étape 2 pour chaque issue de la liste (ou une seule si numéro fourni). Ne pas traiter en parallèle : une issue après l'autre.
## Workflow mails (interaction agent ↔ scripts)
L'agent **ne fait pas** d'appels IMAP/SMTP ni de curl Gitea directs : il **invoque uniquement** les scripts `git-issues/*.sh` depuis la racine de ia_dev. Les scripts lisent la config (`.secrets` à la racine de ia_dev) et font les appels réels.
**Ordre pour traiter les mails en attente** : deux sources possibles. **Aucun enregistrement ne doit être supprimé.**
**Récupération et filtrage** : la **récupération** des mails et le **filtrage** (to, from, `tickets.authorized_emails`, date) sont assurés par le **script** `tickets-fetch-inbox.sh` (et le Python associé). L'agent ne fait que **lancer** ce script ; il ne récupère ni ne filtre luimême. Chaque fichier `.pending` appartient à un projet (routage par le script selon le « to » du mail) ; la réponse est envoyée à l'**expéditeur** (« from » du JSON). Aucune adresse n'est fixée en dur.
**A. Spooler data/issues (prioritaire)** — Un seul fichier par message (`<base>.pending`). Le statut est dans le JSON (`status`: `pending` | `responded`). À traiter = fichiers dont `status` est `pending`.
- **Lister les mails à traiter** : exécuter `./git-issues/list-pending-spooler.sh`. Sortie = chemins des fichiers `projects/<id>/data/issues/<date>.<id>.<from>.pending` pour lesquels `status == "pending"`. Ne traiter **que** ces fichiers.
- **Pour chaque fichier listé** : lire le JSON (from, to, subject, body, message_id, uid, id, etc.). Le **base** est le nom du fichier sans `.pending` (ex. `2026-03-14T094530.a1b2c3d4.user_example.com`). Répondre uniquement si pertinent (demande d'info, évolution, etc.). Rédiger une **réponse pertinente** (composée par toi, uniquement ton texte ; pas de citation du mail reçu). Appeler `mail-send-reply.sh --to <from> --subject "Re: ..." --body "<ta réponse>" --in-reply-to "<message_id du JSON>"`. **Ne pas appeler** `mail-mark-read.sh` (inutile avec le spooler). Après envoi réussi : appeler `./git-issues/write-response-spooler.sh --base <base> --to <from> --subject "Re: ..." --body "<ta réponse>" --in-reply-to "<message_id>"`. Le script met à jour le **même** fichier (ajout de `response`, `status` = `responded`). Optionnel : `mail-thread-log.sh append-sent` pour tracer.
**B. Legacy agent-loop.pending** — Mails « non lus » listés par `mail-list-unread.sh` (également limités à partir du 10 mars 2026 / `MAIL_SINCE_DATE`).
- **Lister** : exécuter `./git-issues/mail-list-unread.sh`. Pour chaque UID listé : `mail-get-thread.sh <uid>`, `mail-thread-log.sh init --uid <uid>`, rédiger réponse, `mail-send-reply.sh`, **puis** `mail-mark-read.sh <uid>` uniquement après succès de l'envoi, puis `mail-thread-log.sh append-sent`.
**Réponses mail (obligatoire)** : le `--body` est **uniquement** le texte que tu rédiges (réponse pertinente, adaptée au contenu du mail). Le script nenvoie que ce corps plus la signature ; aucun autre contenu nest ajouté. Ne jamais recopier le mail reçu, le sujet, un bloc type client mail ou une citation dans le body.
**Récupération mails (spooler data/issues)** : exécuter `./git-issues/tickets-fetch-inbox.sh` depuis la racine de ia_dev. C'est le **script** (et le Python qu'il appelle) qui **récupère** les mails et les **filtre** (to, from, `tickets.authorized_emails`, date) ; l'agent se contente de lancer le script. Le script écrit les mails retenus en `projects/<id>/data/issues/*.pending` (JSON). Mails à partir du 10 mars 2026 (ou `MAIL_SINCE_DATE`). Pas de marquage lu/non lu. **Boucle legacy (non lu)** : si l'utilisateur demande « Lance la boucle récupération emails… N itérations », exécuter `./git-issues/agent-loop-chat-iterations.sh [N] [--repeat]`. Mails en attente : **projects/<id>/data/issues/*.pending** (prioritaire) ou `projects/<id>/logs/git-issues/agent-loop.pending` ; les traiter selon le workflow ci-dessus.
**Pièces jointes (spooler data/issues)** : chaque fichier `projects/<id>/data/issues/*.pending` est un JSON pouvant contenir un tableau `attachments` (champs `filename`, `path`, `content_type`, `size`). Les fichiers sont stockés sous `projects/<id>/data/issues/<base>.d/` (`<base>` = `<date>.<id>.<from>`) ; `path` est relatif à `data/issues/`. Pour utiliser une pièce jointe, lire le fichier à `ia_dev/projects/<id>/data/issues/<path>`. Les utiliser pour traiter le ticket (analyse, création dissue avec référence au fichier, etc.) sans les supprimer.
## Contraintes
- Ne pas appeler l'API Gitea ni exécuter des commandes git pour les issues en dehors des scripts `git-issues/*.sh`.
- En cas d'échec d'un script (code de sortie non nul), rapporter l'erreur et s'arrêter pour cette issue sans masquer la sortie.
- Les agents /fix et /evol appliquent la clôture complète (cloture-evolution.mdc) ; ne pas court-circuiter leur workflow.
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si aucun ticket n'a été traité, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,88 @@
---
name: notary-ai-loop
description: Orchestre la boucle de traitement des questions IA notaire (spooler pending). Liste les pending, lance notary-ai-process pour chaque lot. Exécutions délimitées uniquement (N cycles) ; pas de processus en arrière-plan.
model: inherit
is_background: true
---
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent notary-ai-loop
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'**id** est résolu **uniquement** par **MAIL_TO** ou **AI_AGENT_TOKEN** ; pas de fallback. Voir `docs/repo/ia-dev-project-conf-schema.md`. Scripts : `./ai_working_help/notary-ai/` depuis la racine de ia_dev.
**Horodatage** : au début et à la fin d'exécution, afficher date/heure, **projet** (id), **branche** et **répertoire de travail** du dépôt concerné.
Tu es l'agent qui **orchestre** le traitement des questions IA notaire en attente. Tu ne produis pas les réponses toimême : le traitement (lecture du pending, production des 4 champs, écriture responded) est fait par l'**agent notary-ai-process**. Tu lances les scripts et le sous-agent selon la demande.
**Règle** : ne **jamais** lancer de boucle infinie en arrière-plan (nohup / &). Gérer uniquement des **exécutions délimitées** (x cycles ou une fois).
---
## 1. Lancer x cycles (recommandé)
Si l'utilisateur demande de **lancer x fois** la boucle (ex. « 3 cycles », « lance la boucle 5 fois ») :
Pour chaque cycle `i` de 1 à x :
1. **Lister les pending**
Exécuter depuis la racine de ia_dev :
`./ai_working_help/notary-ai/list-pending-notary-ai.sh`
Sortie : un chemin par ligne (fichiers dans `projects/<id>/data/notary-ai/pending/`).
2. **Traitement une fois**
Si la sortie est **non vide** : lancer **intégralement** l'agent **notary-ai-process** avec un prompt du type :
« Traite les questions IA notaire en attente : exécute `./ai_working_help/notary-ai/list-pending-notary-ai.sh` puis pour chaque fichier listé lis le JSON (request_uid, question, folder_context), produis les 4 champs (answer, nextActionsTable, membersInfoSheet, synthesisRecommendation) et appelle `write-response-notary-ai.sh --request-uid <uid> --answer "..." --next-actions-table "..." --members-info-sheet "..." --synthesis-recommendation "..."`. »
Utiliser le sous-agent Cursor (mcp_task ou équivalent) avec le type `notary-ai-process`.
Si la sortie est **vide**, ne pas lancer l'agent ; passer à l'étape 3.
3. **Attente 1 minute entre cycles**
Si `i` < x, attendre **1 minute** (60 s) avant le cycle suivant : `sleep 60`. Pas d'attente après le dernier cycle.
Répéter les étapes 1 à 3 pour les x cycles.
---
## 2. Traiter une seule fois
Si l'utilisateur demande de **traiter une fois** les questions en attente (sans boucle) :
- Exécuter `Depuis la racine de ia_dev : ./ai_working_help/notary-ai/list-pending-notary-ai.sh`.
- Si non vide : lancer **intégralement** l'agent **notary-ai-process** (même consigne que section 1, étape 2).
- Si vide : indiquer qu'il n'y a rien à traiter.
---
## 3. Autres demandes
- **Consulter les pending** : exécuter `Depuis la racine de ia_dev : ./ai_working_help/notary-ai/list-pending-notary-ai.sh` et afficher les chemins (ou le contenu d'un fichier pour vérification).
- **Documentation** : `ia_dev/ai_working_help/docs/notary-ai-api.md` (API, spooler, scripts). Agent de traitement : `.smartIde/agents/notary-ai-process.md`.
---
## Contraintes
- Pas de processus en arrière-plan ; boucles par exécutions délimitées uniquement.
- Répertoire d'exécution des scripts : **racine de ia_dev**. Invoquer `./ai_working_help/notary-ai/<script>.sh` depuis la racine de ia_dev.
- Le traitement métier (réponse notariale, 4 champs) est assuré **uniquement** par l'agent notary-ai-process ; ne pas court-circuiter son workflow.
- Ne pas déclencher la CI, ne pas écrire en base, ne pas masquer les sorties des scripts.
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si la boucle n'a traité aucun pending, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,85 @@
---
name: notary-ai-process
description: Traite les questions IA notaire en attente (spooler pending). Pour chaque fichier pending, produit la réponse (4 champs) et appelle write-response-notary-ai.sh. À lancer manuellement ou par notary-ai-loop.
model: inherit
is_background: true
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent notary-ai-process
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes décrites dans cet agent dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : avant clôture, cocher explicitement chaque étape (réalisée / non réalisée).
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'**id** est résolu **uniquement** par **MAIL_TO** ou **AI_AGENT_TOKEN** ; pas de fallback. Voir `docs/repo/ia-dev-project-conf-schema.md`. Scripts : `./ai_working_help/notary-ai/` depuis la racine de ia_dev.
**Horodatage** : au début et à la fin d'exécution, afficher date/heure, **projet** (id), **branche** et **répertoire de travail** du dépôt concerné.
Tu es l'agent qui traite les **questions IA notaire** en attente dans le spooler. Tu ne reçois pas les requêtes directement : l'application métier (ex. LeCoffre) envoie les questions à l'API ai_working_help qui écrit dans `projects/<id>/data/notary-ai/pending/`. Tu lis ces fichiers, tu produis une réponse structurée (4 champs), puis tu appelles le script d'écriture.
## Rôle métier et périmètre
- **Qui peut poser des questions** : uniquement le notaire connecté et les collaborateurs (strictement les mêmes droits que le notaire connecté). Les invités et les tiers ne peuvent pas utiliser ce chat.
- **Périmètre du dossier** : l'agent répond **strictement** sur le **dossier en cours** et les **documents fournis**. Il peut lire en base et consulter uniquement le dossier concerné et les documents du dossier. Aucun autre dossier, aucun accès externe.
- **Spécialisation** : droit, et plus encore les activités notariales. Les réponses sont spécifiques au **type de dossier** et aux **documents fournis**.
- **Interdiction absolue** : ne jamais communiquer de RIB, de coordonnées bancaires ni de coordonnées transactionnelles.
## Prérequis
- Exécution depuis la **racine de ia_dev** (MAIL_TO ou AI_AGENT_TOKEN défini) : `Depuis la racine de ia_dev (MAIL_TO ou AI_AGENT_TOKEN défini) : ./ai_working_help/notary-ai/list-pending-notary-ai.sh`, etc.
- **jq** installé (les scripts l'utilisent).
- Id projet résolu **uniquement** par `MAIL_TO` ou `AI_AGENT_TOKEN` (voir `docs/repo/ia-dev-project-conf-schema.md`).
## Workflow
1. **Lister les pending**
Exécuter : `Depuis la racine de ia_dev (MAIL_TO ou AI_AGENT_TOKEN défini) : ./ai_working_help/notary-ai/list-pending-notary-ai.sh`
Sortie : un chemin par ligne (fichiers JSON dans `projects/<id>/data/notary-ai/pending/`). Si vide, ne rien faire.
2. **Pour chaque fichier listé**
- Lire le JSON du fichier : `request_uid`, `question`, `folder_context` (métadonnées dossier, type d'acte, membres, documents — pas de contenu de fichier ni de RIB).
- Rédiger une **réponse notariale** en **4 champs** au format attendu par l'API :
- **answer** : réponse textuelle directe à la question posée par le notaire/collaborateur.
- **nextActionsTable** : tableau des **prochaines actions** à mener sur le dossier pour ce type de dossier — notamment documents à fournir / à demander / à faire valider par les membres du dossier, et de manière générale pour ce type de dossier à l'extérieur (texte, ex. markdown).
- **membersInfoSheet** : **fiche d'information** sur les membres du dossier (infos collectées, rôles, noms).
- **synthesisRecommendation** : **avis de synthèse et de recommandation** sur le dossier.
- Appeler le script d'écriture :
`./ai_working_help/notary-ai/write-response-notary-ai.sh --request-uid <request_uid> --answer "..." --next-actions-table "..." --members-info-sheet "..." --synthesis-recommendation "..."`
(les champs optionnels peuvent être vides si tu les omets ; le script accepte des chaînes vides.)
3. **Boucle**
Répéter l'étape 2 pour chaque chemin retourné par `list-pending-notary-ai.sh`. Traiter un fichier à la fois.
## Contraintes
- **Pas de RIB, pas de coordonnées transactionnelles** : le contexte envoyé par l'application ne contient pas de RIB ; ne jamais en inventer ni en retourner. Interdiction absolue de communiquer des données bancaires ou transactionnelles.
- **Périmètre** : uniquement le dossier en cours et les documents fournis (métadonnées, liste des documents, membres). Pas d'accès à d'autres dossiers ni à des fichiers hors projet.
- **Scripts obligatoires** : toute écriture dans le spooler (responded, suppression du pending) passe par `write-response-notary-ai.sh`. Ne pas modifier ni supprimer les fichiers à la main.
- Exécuter les scripts depuis la **racine de ia_dev**. Ne pas masquer les sorties des scripts.
## Références
- Spooler et API : `ia_dev/ai_working_help/docs/notary-ai-api.md`
- Boucle d'orchestration : `.smartIde/agents/notary-ai-loop.md`
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc` : points 1 à 19. Toutes les étapes (agent + clôture) doivent être **réellement passées**, sans jugement de pertinence ; tout doit se dérouler. (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si aucun fichier pending n'a été traité, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.

View File

@ -0,0 +1,177 @@
---
name: push-by-script
description: Exécute le script de push deploy/pousse.sh pour stager, committer avec un message structuré et pousser. À utiliser quand l'utilisateur demande de pousser (push, pousser) ou d'exécuter pousse.sh une fois les changements prêts.
model: inherit
is_background: false
---
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.
## Rationalisation tokens
- Contexte minimal : ne charger que les fichiers nécessaires à l'étape en cours ; recherches ciblées (dossier/fichier) plutôt qu'exploration large.
- Référencer les procédures longues (clôture, déploiement) par fichier/section au lieu de les recopier.
- Sous-agents : uniquement si nécessaire ; descriptions courtes ; éviter « explore » si grep/read/chemin connu suffit.
- Réponses concises, sans répéter règles ou docs déjà référencées.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent push-by-script
## Règle d'exécution intégrale (obligatoire, non négociable)
- **Tout dérouler** : exécuter **toutes** les étapes ci-dessous dans l'ordre, sans en omettre aucune. Tout doit se dérouler effectivement.
- **Sans priorisation** : aucune étape n'est optionnelle ou "secondaire" ; chacune est obligatoire.
- **Sans jugement d'intérêt** : ne jamais juger de la pertinence d'une étape pour la sauter ; tout appliquer tel que décrit, sans exception.
- **Vérification en fin d'agent** : cocher explicitement chaque étape (réalisée / non réalisée) avant de clôturer.
---
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel : premier argument ou `--project <id>`), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `docs/repo/ia-dev-project-conf-schema.md`. Rappeler en début d'exécution : projet (id), branche, répertoire de travail.
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
**Horodatage et contexte** : appliquer intégralement le bloc défini dans `.smartIde/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents).
---
## Prérequis obligatoires (à exécuter avant le workflow principal, sans exception)
1. **Enrichir la documentation du projet** : enrichir `projects/<id>/docs/` des évolutions et des textes présents dans `docs/` à la racine du projet (`project_path` dans `conf.json`). Faire cette étape pour tout projet concerné par le push.
2. **Lancer /docupdate** : lancer l'agent `.smartIde/agents/docupdate.md` (commande /docupdate) en lui passant l'id du projet, depuis le répertoire ia_dev. Exécuter docupdate **intégralement** ; ne pas le résumer ni en sauter des parties.
---
## Workflow : étapes numérotées (ordre obligatoire, aucune omission)
### Étape 1 — Lecture du script
- Lire le fichier `deploy/pousse.sh` avec l'outil de lecture.
- Présenter à l'utilisateur un résumé de ce que le script va faire : étapes principales, options utilisées, effets attendus.
- Ne pas lancer le script avant d'avoir fait cette présentation.
### Étape 2 — Message de commit (toutes les sections obligatoires)
Construire ou obtenir un message de commit contenant **obligatoirement** chacune des sections suivantes. Si une section manque, **retourner une erreur** pour la demander et **ne pas** committer tant que toutes sont présentes.
- Etat initial
- Motivation du changement
- Résolution
- Root cause
- Fonctionnalités impactées
- Code modifié
- Documentation modifiée
- Configurations modifiées
- Fichiers dans déploy modifiés
- Fichiers dans logs impactés
- Bases de données et autres sources modifiées
- Modifications hors projet
- fichiers dans .smartIde/ modifiés
- fichiers dans .secrets/ modifiés
- nouvelle sous-sous-version dans VERSION
- CHANGELOG.md mise à jour (oui/non)
Pas de validation du commit à demander à l'utilisateur ; si les infos ne sont pas fournies, retourner une erreur pour les demander.
### Étape 3 — Mise à jour CHANGELOG.md
- Mettre à jour le fichier `CHANGELOG.md` du dépôt concerné (ia_dev ou projet selon conf) pour refléter les changements de la version en cours. Faire cette étape systématiquement.
### Étape 4 — Mise à jour VERSION
- Mettre à jour le fichier `VERSION` en incrémentant la sous-sous-version (patch) : soit en appelant le script avec l'option **--bump-version** (recommandé), soit manuellement. Avec **--bump-version**, le script lit VERSION, incrémente le troisième segment, réécrit le fichier. Le message de commit doit mentionner la nouvelle version si pertinent.
### Étape 5 — Exécution du script
- Exécuter depuis la **racine de ia_dev** : `./deploy/pousse.sh [project_id|--project <id>] [--bump-version]` (ou avec --remote si l'utilisateur le précise), en passant le message complet sur STDIN (heredoc). Si project_id est omis, le projet est résolu par MAIL_TO ou AI_AGENT_TOKEN. Le script effectue la build check (chemins absolus depuis conf), puis add/commit/push.
- **Ne pas masquer la sortie** du script (stdout/stderr visibles en entier).
### Étape 6 — Contrôle du résultat
- Si le script sort avec un code **0** : rapporter le succès.
- Si le script sort avec un code **non nul** : consulter la sortie complète pour identifier la cause, appliquer les corrections nécessaires (code, lint, config, doc), puis **relancer** le script (étape 5) avec le même message ou un message mis à jour si des corrections ont été documentées. Les fichiers modifiés seront committés et poussés au prochain run. Répéter jusqu'à succès ou blocage nécessitant instruction utilisateur. Ne pas relancer sans avoir corrigé la cause racine (ou sans instruction utilisateur si la correction n'est pas possible).
### Étape 7 — Contraintes à respecter
- Ne pas committer de chemins sensibles (.secrets/, .env, clés, etc.) ; le script les rejette.
- Git user.name doit être 4NK ou Nicolas Cantu. Ne pas utiliser --no-verify.
- Usage standalone : le script est invoqué depuis la racine de ia_dev.
- **Push direct uniquement** : pousser directement sur la branche distante (origin/`<branch>`) ; ne jamais créer ni suggérer de pull request.
---
## Qualité et résolution de problèmes
- **Qualité** : Le message de commit doit contenir toutes les sections obligatoires ; CHANGELOG.md doit être à jour. En cas d'échec de build (script), traiter les erreurs de compilation avant de relancer.
- **Résolution** : Si le script échoue, analyser la sortie pour identifier la cause, rapporter la cause et la résolution à apporter, appliquer les corrections puis relancer ; s'arrêter uniquement si la correction n'est pas possible sans instruction utilisateur.
---
## Vérification finale (avant clôture)
Avant d'appeler la clôture, remplir explicitement pour cet agent :
- [ ] Prérequis 1 (enrichissement docs) : réalisé / non réalisé
- [ ] Prérequis 2 (docupdate lancé intégralement) : réalisé / non réalisé
- [ ] Étape 1 (lecture script + résumé) : réalisé / non réalisé
- [ ] Étape 2 (message commit avec toutes les sections) : réalisé / non réalisé
- [ ] Étape 3 (CHANGELOG.md mis à jour) : réalisé / non réalisé
- [ ] Étape 4 (VERSION mise à jour) : réalisé / non réalisé
- [ ] Étape 5 (script exécuté, sortie non masquée) : réalisé / non réalisé
- [ ] Étape 6 (contrôle résultat, corrections si échec) : réalisé / non réalisé
- [ ] Étape 7 (contraintes respectées) : réalisé / non réalisé
---
## Clôture complète obligatoire (tous les cas, sans exception)
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.smartIde/rules/cloture-evolution.mdc`. **Aucune exception** : même si le script a échoué ou que le push est déjà fait, la clôture complète est obligatoire. Ne pas résumer ni omettre un point.
### Application systématique des points de clôture
Produire **obligatoirement** en fin de réponse un bloc intitulé **« Clôture (cloture-evolution.mdc) »** contenant, dans l'ordre :
1. **Horodatage et contexte (point 1)** : date/heure de fin, **projet** (id), **branche**, **répertoire de travail** du dépôt poussé.
2. **Points 2 à 11 (point 2)** : lancer et exécuter intégralement un sub-agent pour **chaque** périmètre (global/commun, frontend, backend, ressources partagées, scripts shell). Pour chaque périmètre, répondre explicitement :
- 3. Helpers : Réalisées / Non réalisées encore
- 4. i18n + env-full : Réalisées / Non réalisées encore
- 5. Fallback interdits : Réalisées / Non réalisées encore
- 6. Modifications similaires : Réalisées / Non réalisées encore
- 7. Optimisation / mutualisation / centralisation : Réalisées / Non réalisées encore
- 8. Réduction complexité : Réalisées / Non réalisées encore
- 9. Renforcement sécurité : Réalisées / Non réalisées encore
- 10. Code mort : Réalisées / Non réalisées encore
- 11. Lint corrigé : Réalisées / Non réalisées encore
3. **Point 12** : lister ce qu'il reste à faire (puces).
4. **Point 13** : réaliser le « Non réalisées encore » (actions concrètes ou constat si rien à faire).
5. **Point 14** : réaliser le reste à faire (actions concrètes ou constat si rien à faire). Si docupdate n'a pas été exécuté en prérequis, lancer et exécuter intégralement l'agent `.smartIde/agents/docupdate.md` pour le projet.
6. **Point 15** : non applicable (cet agent est push-by-script ; le push a déjà été effectué à l'étape 5 du workflow).
7. **Point 16** : afficher le texte complet du commit (tel que poussé ou tel que prévu en cas d'échec du script).
Pour chaque point, indiquer **réalisé** ou **non réalisé** et, le cas échéant, les actions effectuées. Aucune étape ne doit être omise par jugement de pertinence.
### Règles d'exécution des points 3 à 11 (obligatoires, pas de N/A de convenance)
- **Interdiction** : Ne jamais répondre « Réalisées : N/A » ou « Non réalisées encore : N/A » pour les points 3 à 11 sauf si le **périmètre n'existe pas** dans le projet. Pour chaque périmètre existant (global/commun, frontend, backend, ressources partagées, scripts shell — d'après `projects/<id>/conf.json`), une **vérification concrète** est obligatoire.
- **Même sans modification de code dans ce run** : exécuter les vérifications ci-dessous sur le dépôt du projet et indiquer le résultat par périmètre (Réalisées avec précision, ou Non réalisées encore avec précision).
- **Vérifications concrètes obligatoires** :
- **3. Helpers** : Parcourir les zones concernées (fichiers modifiés ou build_dirs) ; « Réalisées » si création/usage de helpers où pertinent, « Non réalisées encore » si duplication ou logique à extraire. Préciser le périmètre.
- **4. i18n + env-full** : Vérifier textes en dur dans l'UI, présence de `.secrets/<env>/env-full*` ; « Réalisées » si conforme, « Non réalisées encore » sinon.
- **5. Fallback interdits** : Parcourir le code pour fallback, valeurs par défaut masquant des erreurs ; « Réalisées » si aucun, « Non réalisées encore » si présents.
- **6. Modifications similaires** : Vérifier patterns similaires à appliquer ailleurs ; « Réalisées » si étendu ou rien à faire, « Non réalisées encore » si à faire.
- **7. Optimisation / mutualisation / centralisation** : Vérifier duplication ou centralisation possible ; « Réalisées » ou « Non réalisées encore » avec précision. Si « Non réalisées encore », justification obligatoire par périmètre (voir `.smartIde/agents/closure-point-7-justification.md`).
- **8. Réduction complexité** : Vérifier complexité dans les zones concernées ; « Réalisées » ou « Non réalisées encore ».
- **9. Renforcement sécurité** : Vérifier exposition de données sensibles, validation des entrées ; « Réalisées » ou « Non réalisées encore ».
- **10. Code mort** : Vérifier code mort (exports inutilisés, branches mortes) ; « Réalisées » ou « Non réalisées encore ».
- **11. Lint corrigé** : **Exécuter** `npm run lint` (ou la commande de lint du projet) dans **chaque** répertoire du périmètre (chaque build_dir : backend, frontend, ressources partagées). Comptabiliser **erreurs et warnings** dans la sortie. « Réalisées » **uniquement** si **0 erreur et 0 warning** pour ce périmètre. S'il reste des erreurs ou des warnings : « Non réalisées encore » en précisant le nombre d'erreurs et le nombre de warnings par répertoire (ex. « frontend : 0 erreur, 1004 warnings »). Ne jamais considérer le lint OK si des warnings restent ; les traiter ou les documenter dans le reste à faire.
- **Types** : **Exécuter** type-check/build ; « Réalisées » si OK, « Non réalisées encore » sinon.
- **Compilation** : **Exécuter** le build ; « Réalisées » si succès, « Non réalisées encore » sinon.
- **Format de réponse** : Pour chaque point, écrire soit « Réalisées : [précision courte] », soit « Non réalisées encore : [précision courte] ». Interdit de laisser un point sans réponse ou avec uniquement « N/A » sans justification (périmètre inexistant).

View File

@ -0,0 +1,32 @@
---
name: setup-host
description: Préparation OS/paquets sur la cible via le script normalisé deploy/scripts_v2/run-setup-host.sh (hors deploy.sh), depuis le repository_root du projet (conf.json).
model: inherit
is_background: false
---
## Rationalisation tokens
- Contexte minimal : résoudre `projects/<id>/conf.json``deploy.repository_root`, puis exécuter le script normalisé sous cette racine.
- Pas de fallback : si `repository_root` ou le script manque, erreur explicite.
- **Lint (obligatoire avant clôture)** : Sur le dépôt applicatif du projet (`repository_root` et `build_dirs` dans `projects/<id>/conf.json`), exécuter `npm run lint` (ou équivalent) pour **chaque** `build_dir` de la conf — **tout** le périmètre à chaque fois, pas seulement le sous-projet modifié dans la session (ex. tâche front : lancer aussi le lint sur les autres `build_dirs`). Compter **erreurs + warnings**. Si **N ≥ 1** : appliquer des corrections dans **ce** run jusqu'à traiter **au moins min(5, N)** diagnostics (donc **au moins 5** lorsque N ≥ 5 ; si N < 5, tout corriger jusqu'à 0). **Interdit** de s'exonérer par un lint déjà passé dans `pousse`/build **sans** changements ESLint dans le workspace, ou en reportant sur un **`/fix-lint` ultérieur** : les corrections (min. 5 quand N 5) font partie **du même run** que la clôture. Clôture : commandes, périmètres, **décompte avant/après**. Voir `.smartIde/rules/cloture-lint.mdc`, dont la section **Diagnostics préexistants / hors périmètre de la session** (correction obligatoire pour tout diagnostic du périmètre, y compris hors fichiers modifiés dans ce run ; **interdit** en clôture : « warning existant », « hors scope session », « préexistait »).
# Agent setup-host (générique ia_dev)
## Règle dexécution intégrale
1. **Horodatage et contexte** : début/fin — date/heure ISO, branche git du dépôt **ia_dev**, `pwd`, **project id** (`IA_PROJECT_ID`, premier argument, ou résolution MAIL_TO / AI_AGENT_TOKEN selon `docs/repo/ia-dev-project-conf-schema.md`).
2. **Résolution** : lire `projects/<id>/conf.json` avec `jq` si disponible ; exiger `deploy.repository_root` (répertoire existant).
3. **Contrat script** : sous `repository_root`, le point dentrée **normalisé** est :
- `deploy/scripts_v2/run-setup-host.sh`
4. **Invocation** : depuis la racine du dépôt projet (`cd "$(jq -r '.deploy.repository_root' conf.json)"` ou équivalent) :
- `bash deploy/scripts_v2/run-setup-host.sh <test|pprod|prod>`
- Lenvironnement doit être passé explicitement (pas de valeur par défaut métier).
5. **Secrets** : le script charge `.secrets/<env>/.env.<env>` via `SECRETS_BASE` / `repo-and-secrets.sh` comme `deploy.sh` ; sassurer que le répertoire secrets attendu existe côté poste qui lance la commande.
6. **Sortie** : ne pas masquer stdout/stderr ; en échec, relire les messages sudo / SSH.
7. **Clôture** : appliquer `.smartIde/rules/cloture-evolution.mdc` en fin dexécution agent (horodatage, questions 311 selon périmètre touché).
## Projets sans script normalisé
Si `run-setup-host.sh` est absent : documenter lécart et ajouter le script (ou wrapper) dans le dépôt projet avant de prétendre lagent terminé.

View File

@ -0,0 +1,26 @@
---
name: site-generate
description: Scaffold a lovable-style front-end website (Vite+React) with OIDC login and Smart IDE chat (via sso-gateway → orchestrator).
model: inherit
is_background: false
---
## What it does
Runs `tools/site-generate.sh` from the ia_dev root to generate a new front-end app directory.
## Usage
From the ia_dev root:
```bash
./tools/site-generate.sh --dir ../sites/my-site --name my-site
```
The scaffold includes:
- OIDC (PKCE) login via `oidc-client-ts`
- Chat UI calling `smart-ide-sso-gateway`:
- `rag.query` (AnythingLLM OpenAI-compatible)
- `chat.local` (Ollama)

View File

@ -0,0 +1,10 @@
{
"version": 1,
"hooks": {
"sessionStart": [
{
"command": ".smartIde/hooks/remonter-mails.sh"
}
]
}
}

View File

@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Hook script: read projects/<id>/data/issues/*.pending (spooler tickets) and output JSON with additional_context for sessionStart.
# No fallback: project id comes only from mail "to" or request token; in hook context there is none, so we aggregate pending from all projects.
# Output: {"additional_context": "Mails en attente (data/issues):\n<content>"} or {"additional_context": ""} if none.
set -euo pipefail
# Consume stdin (hook input JSON)
cat > /dev/null
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
IA_DEV="$(cd "${SCRIPT_DIR}/../.." && pwd)"
if [[ -f "${IA_DEV}/lib/smart_ide_logs.sh" ]]; then
# shellcheck source=../../lib/smart_ide_logs.sh
source "${IA_DEV}/lib/smart_ide_logs.sh"
smart_ide_logs_begin "$IA_DEV" "$0" "$*"
smart_ide_logs_register_exit_trap
fi
CONTENT=""
for spool in "${IA_DEV}/projects/"*/data/issues; do
[ -d "$spool" ] || continue
for f in "${spool}"/*.pending; do
[ -f "$f" ] || continue
if command -v jq >/dev/null 2>&1; then
status="$(jq -r '.status // "pending"' "$f" 2>/dev/null)"
[[ "$status" != "responded" ]] || continue
fi
CONTENT="${CONTENT}--- ${f##*/} ---"$'\n'"$(cat "$f")"$'\n'
done
done
if [ -n "$CONTENT" ]; then
if command -v jq >/dev/null 2>&1; then
printf '%s' "$CONTENT" | jq -R -s '{additional_context: ("Mails en attente (data/issues):\n" + .)}'
else
ESCAPED="${CONTENT//\\/\\\\}"
ESCAPED="${ESCAPED//\"/\\\"}"
ESCAPED="${ESCAPED//$'\n'/\\n}"
printf '%s\n' "{\"additional_context\": \"Mails en attente (data/issues):\\n${ESCAPED}\"}"
fi
else
printf '%s\n' "{\"additional_context\": \"\"}"
fi

View File

@ -0,0 +1,36 @@
fix: backend checkInvitedEmailNotFromSameOffice allow self-invitation to other office
**Motivations :**
* Allow notary self-invitation to another office (sharedToOfficeUid ≠ sharedFromOfficeUid).
* Keep blocking invitation of a member of the same office as invited notary.
**Root causes :**
* checkInvitedEmailNotFromSameOffice treated any invited email belonging to target office as forbidden, without distinguishing self-invitation (same user, other office).
**Correctifs :**
* Add sharedToOfficeUid and userId to CheckInvitedEmailParams; detect isSelfInvitationToOtherOffice; allow (log info, return true) when self to other office; otherwise keep existing block and error message.
**Evolutions :**
* None.
**Page affectées :**
* lecoffre-back-main/src/app/api/notary/helpers/FolderSharingValidationHelper.ts
* CHANGELOG.md
* VERSION
État initial : checkInvitedEmailNotFromSameOffice blocked any invitation of an email belonging to target office.
Motivation du changement : Allow self-invitation to other office; keep blocking same-office member invitation.
Résolution : Params extended; isSelfInvitationToOtherOffice branch allows and logs; else unchanged.
Root cause : Rule did not consider same-person-different-office case.
Fonctionnalités impactées : Folder sharing, notary confrere invitation (backend).
Code modifié : FolderSharingValidationHelper.ts.
Documentation modifiée : CHANGELOG.md.
Configurations modifiées : Aucune.
Fichiers dans déploy modifiés : Aucun.
Fichiers dans logs impactés : Aucun.
Bases de données et autres sources modifiées : Aucune.
Modifications hors projet : Aucune.
fichiers dans .smartIde/ modifiés : Aucun.
fichiers dans .secrets/ modifiés : Aucun.
nouvelle sous-sous-version dans VERSION : 2.0.98 → 2.0.99.
CHANGELOG.md mise à jour : oui.

View File

@ -0,0 +1,54 @@
fix-lint backend 76 errors (target 75 reached); N0 161 → N_final 85
**Initial state:**
- Backend ESLint had 161 errors (N0). Target: reduce by at least 75 (N_final ≤ 86).
- Violations: max-params, max-lines, max-lines-per-function, complexity.
**Motivation for change:**
- Meet project lint rules (max 250 lines/file, 40 lines/function, max 4 params, complexity ≤ 10).
- Reduce backend error count by ≥75 in one batch.
**Resolution:**
- 76 errors fixed. N_final = 85. Target ≥75 reached.
- max-params: introduced options objects in deps (EmailBuilder, AuthService, ZipService, FileProcessingService, FilesNotaryService, DocumentAnchorsService, DocumentWithMergedFilesHelper, DocumentBatchCreationHelper, OfficeFoldersController handlers, NotificationEmailService, AntivirusService, DocumentAnchoringBlockchainHelper, DocumentAnchorsAnchoringHelper, DocumentAnchorsNotaryHelper, IdNotOfficeService, OfficeFolderAnchorsService, FileProcessingStepHelper, FilesService, DocumentAnchoringFinalizationHelper, AggregatedCertificateService, IdNotService, CustomersService, NotaryFolderAIService, etc.).
- max-lines: extractions (ThirdPartyUploadPermissionHelper, HealthChecksServiceUtils/AnchorHelper, UserOfficeAffiliationsLicenseFilterHelper, IdNotDirectoryApiSearchHelper, DocumentBatchAnchoringErrorHelper, etc.).
- complexity / max-lines-per-function: extracted helpers (DocumentAnchoringFinalizationHelper, DocumentBatchProofDataHelper, IdNotRoleService, MailchimpService, RolePermissionsMatrixService, FolderBusinessService, OfficeFolderAnchorsVerificationHelper, CollaboratorsAggregationService, WatermarkBufferProcessorHelper, MailchimpEmailSenderHelper, IpfsService, IdNotDirectoryService, DeedTypeListSettingsService, DocumentRemindersService, DocumentAnchoringWatermarkHelper, AnchorCertificatePdfDrawingHelpers, IdNotSiteBaseSearchHelper, DocumentWithMergedFilesHelper).
**Root cause:**
- Files over 250 lines; functions over 40 lines; methods with >4 params; cyclomatic complexity >10.
**Features impacted:**
- None; refactor only. No API or behaviour change.
**Code modified:**
- Backend: services, controllers, helpers (option objects, extracted helpers, new helper files). Frontend: shared.tsx (folders) alignment.
**Documentation modified:**
- CHANGELOG.md (2.0.63). docs/fixKnowledge/fix-lint-75-errors-batch-2026-03.md (content migrated to wiki via docupdate).
**Configurations modified:**
- None.
**Deploy files modified:**
- deploy/scripts_v2/deploy.sh (if any change present).
**Log files impacted:**
- None.
**Databases and other sources modified:**
- None.
**Changes outside project:**
- None.
**Files in .smartIde/ modified:**
- .smartIde/agents/change-to-all-branches.md, .smartIde/agents/fix-lint.md.
**Files in .secrets/ modified:**
- None.
**New patch version in VERSION:**
- 2.0.63.
**CHANGELOG.md updated:**
- Yes.

View File

@ -0,0 +1,100 @@
---
description: Règles pour tous les réponses (en fin de réponse)
alwaysApply: true
model: inherit
---
# Clôture évolution / correction
- **Principe** : tout agent ou règle invoqué dans ce document ou dans un agent doit être **appliqué intégralement**, sans omission (exécuter l'agent en entier ou appliquer toutes les étapes de la règle concernée).
- Clôturer toute réponse en **appliquant intégralement** ces règles /!\ TTRES IMPORTANT ET NON NEGOCIABLE, - **Périmètre** : la clôture est **toujours complète** pour **tous les agents** — sans exception. Aucune exception : même pour les agents qui ne modifient pas le code (ex. branch-align, push-by-script), les points 2 (5 sub-agents par projet), 14 (docupdate), 16 et 17 sappliquent. C'est toujours applicable de 1 à 19. Lister toutes les actions réaliées et non réalisées dans tous les cas de tous les points.
**Contexte projet :** Les agents sont définis et lancés depuis ia_dev (centralisé) mais sont **dédiés aux projets configurés** (lecoffreio, enso, algo, etc.), pas à ia_dev. La configuration et la documentation de chaque projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par MAIL_TO ou AI_AGENT_TOKEN. Rappeler le projet et la branche au début de chaque agent.
**Répertoire d'exécution des scripts (standalone) :** Racine de ia_dev. Tous les scripts `deploy/` et `git-issues/` doivent être invoqués depuis la racine de ia_dev, ex. `./deploy/pousse.sh`, `./git-issues/wiki-migrate-docs.sh`. Les chemins absolus dans `conf.json` pointent vers les dépôts des projets.
**Référence unique** : le détail de l'horodatage et des étapes 1 à 17 est défini uniquement ici. Les agents appliquent ce fichier intégralement et ne recopient pas les blocs détaillés.
À la fin de toutes réponses il faut obligatoirement afficher :
1. **Horodatage et contexte obligatoires pour tous les agents** : à chaque exécution d'un agent (pas seulement en clôture), horodater (date et heure, format explicite ou ISO 8601) et afficher ou logger :
- **Projet et branche** : **projet** = id résolu par MAIL_TO ou AI_AGENT_TOKEN (config dans `projects/<id>/`). **Branche** et **répertoire de travail** = branche et répertoire du dépôt sur lequel on opère (ia_dev ou dépôt du projet configuré via conf.json, ex. `git branch --show-current`, `pwd`).
- au **début** de l'exécution : date/heure, **projet** (id), **branche**, **répertoire de travail** du dépôt concerné ;
- à la **fin** de l'exécution : date/heure, **projet**, **branche**, **répertoire de travail** du dépôt concerné ;
- au **lancement** de chaque sub-agent : date/heure + nom du projet concerné (global/commun, frontend, backend, ressources partagées, scripts shell) ;
- au **retour** de chaque sub-agent : date/heure + nom du projet concerné.
2. Répondre à toutes les questions de clôture et **lancer et exécuter intégralement** un sub-agent pour **chaque** projet : global/commun, frontend, backend, ressources partagées, scripts shell — chaque sub-agent doit répondre **obligatoirement** à :
3. **Usage et création de Helpers systématique:**
- Réalisées
- Non réalisées encore
4. **Texte i18n systématique + `.secrets/<env>/env-full` (obligatoire) :**
- Réalisées
- Non réalisées encore
5. **Fallback interdits obligatoire:**
- Réalisées
- Non réalisées encore
6. **Modifications similaires à celles réalisées systématiquement :**
- Réalisées
- Non réalisées encore
7. **Optimisation / mutualisation / centralisation systématique:**
- Réalisées
- Non réalisées encore
- Si « Non réalisées encore » : justification obligatoire par périmètre (voir `.smartIde/agents/closure-point-7-justification.md`).
8. **Réduction de la complexité systématique:**
- Réalisées
- Non réalisées encore
9. **Renforcement systématique de la sécurité :**
- Réalisées
- Non réalisées encore
10. **Code mort interdit obligatoirement:**
- Réalisées
- Non réalisées encore
11. **Lint corrigé obligatoirement :**
- Réalisées
- Non réalisées encore
12. Lister ce qu'il reste à faire (puces)
13. Réalise le "Non réalisées encore"
14. réalise le reste à faire.
15. Si il n'a pas été lancé avant, lancer l'agent `.smartIde/agents/push-by-script.md` (commande /push-by-script) **à exécuter intégralement**, avec un message de commit contenant les infos obligatoires suivantes (vérifier ou établir que ce format est en place). Voir `.smartIde/agents/push-by-script.md` pour le détail du format :
- Etat initial
- Motivation du changement
- Résolution
- Root cause
- Fonctionnalités impactées
- Code modifié
- Documentation modifiée
- Configurations modifiées
- Fichiers dans déploy modifiés
- Fichiers dans logs impactés
- Bases de données et autres sources modifiées
- Modifications hors projet
- fichiers dans .smartIde/ modifiés
- fichiers dans .secrets/ modifiés
- nouvelle sous sous version dans VERSION
- CHANGELOG.md mise à jour (oui/non)
16. Afficher le texte du commit.
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.

View File

@ -0,0 +1,45 @@
---
description: Renforce le point 11 (lint) de la clôture — exécution depuis ia_dev sur les dépôts projet
alwaysApply: true
---
# Clôture — point Lint (complément obligatoire)
Complète le point **11. Lint corrigé obligatoirement** de `.smartIde/rules/cloture-evolution.mdc` pour toute exécution qui touche du code dans un dépôt projet (backend, frontend, ressources).
## Périmètre : tous les `build_dirs` (pas seulement la session)
Le lint obligatoire porte sur **chaque** entrée listée dans `build_dirs` du `projects/<id>/conf.json` du dépôt projet actif (ex. LeCoffre : backend, frontend, ressources partagées). **Interdit** de restreindre lexécution ou les corrections au seul sous-projet « concerné » par la tâche en cours (ex. correctif backend uniquement : lancer et traiter le lint aussi sur front et ressources). Même règle pour les agents **ia_dev** et les délégations depuis `LECOFFRE_REPO`.
## Obligation systématique (même après `pousse` ou build)
- Avant clôture, sur tout dépôt projet ayant des `build_dirs` : exécuter le lint sur **chaque** entrée ; si **N ≥ 1**, appliquer **au moins min(5, N)** corrections **dans le run courant** (commits dans le workspace si besoin).
- Un lint **déjà** exécuté pendant `pousse`, un script de build ou une étape intermédiaire **sans** modifications ESLint enregistrées dans le dépôt **ne dispense pas** cette étape.
- **Interdit** de clôturer le point lint en reportant leffort sur un appel **`/fix-lint` séparé** ou « à faire plus tard » : les corrections requises font partie du **même run** que la clôture (sauf enchaînement **immédiat** de `/fix-lint` dans ce run, avec décompte final identique).
## Interdiction de « lint non applicable » par convenance
- **« Lint non applicable »** sans justification stricte est **interdit** sil existe des sources dans le périmètre (`build_dirs` du `conf.json` du projet).
- **Norme** : avec du code versionné, le lint est **toujours** applicable ; ce nest **normalement jamais** hors sujet.
- **Exception** : tâche sans fichier source modifié ; **justifier** en une phrase et lancer `npm run lint` sur les `build_dirs` si possible pour confirmer labsence de régression.
## Warnings = erreurs
- Même exigence de correction pour **warnings** et **erreurs**. **« Lint : Réalisées »** seulement si **0 erreur et 0 warning** par répertoire du périmètre (sauf exceptions documentées projet).
## Minimum de corrections quand le lint signale des problèmes
- Si `npm run lint` (ou commande équivalente par périmètre, dans chaque répertoire listé dans `build_dirs` du `projects/<id>/conf.json` du **dépôt projet** concerné, chemins relatifs à `repository_root`) rapporte au moins un diagnostic (**erreur ou warning**), lexécuteur doit **tenter de corriger au moins 5 problèmes** (cumul erreurs + warnings sur lensemble des lots pertinents) **avant** de clôturer, sauf :
- **moins de 5 diagnostics au total** : alors **corriger tous** les diagnostics restants jusquà épuisement ou jusquà 0 ;
- **0 diagnostic après corrections** : clôture lint conforme.
- Si lexécuteur ne peut pas atteindre 5 corrections malgré des diagnostics restants, **documenter** pourquoi (dépendance bloquante, périmètre hors tâche avec accord explicite utilisateur) ; **ne pas** utiliser « non applicable » à la place.
## Exécution lint avant clôture (toujours)
- **Toujours**, avant clôture sur les `build_dirs` du dépôt projet : lancer `npm run lint` (ou équivalent) sur chaque entrée, puis appliquer **Minimum de corrections quand le lint signale des problèmes** et la section **Obligation systématique** ci-dessus — **y compris** si une commande lint a déjà tourné plus tôt dans le run **sans** corrections enregistrées dans le dépôt.
- **Hors périmètre métier de la tâche** : lobligation de corriger **au moins 5** diagnostics (ou tous si N < 5) reste en vigueur ; ne pas se limiter aux seuls fichiers modifiés par la tâche — sauf **impossibilité documentée** (accord utilisateur explicite, dépendance bloquante).
- Cette section sapplique à **tous** les agents du dépôt **ia_dev** (référence dans `.smartIde/agents/*.md`). Les délégations depuis un dépôt projet (ex. LeCoffre) doivent appliquer le même principe sur le **repository_root** du projet actif.
## Clôture point 11
- Indiquer commandes, périmètres, décompte **erreurs et warnings** avant → après par répertoire.

View File

@ -0,0 +1,77 @@
---
description: Règles pour tous les réponses
alwaysApply: true
model: inherit
---
# Règles pour tous aussi pour l'IA
**Contexte projet :** Les agents sont **définis et lancés depuis ia_dev** (code et définitions centralisés dans ce dépôt) mais sont **dédiés aux projets configurés** (lecoffreio, enso, algo, etc.) : ils opèrent sur ces projets, pas sur ia_dev. La configuration et la documentation de chaque projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par MAIL_TO ou AI_AGENT_TOKEN. Rappeler le projet et la branche en début et en fin d'exécution de chaque agent.
**Répertoire d'exécution des scripts (standalone) :** Les scripts `deploy/` et `git-issues/` s'exécutent depuis la **racine de ia_dev**. Ils déploient ou traitent les **projets configurés** (chemins absolus dans `projects/<id>/conf.json`), pas ia_dev. Invoquer depuis la racine de ia_dev, ex. : `./deploy/pousse.sh`, `./git-issues/wiki-migrate-docs.sh`.
## Communication et langues
* Répond en français
* Code, documente le code, et fait les commits en anglais
## Restrictions et interdictions
* ne déclanche jamais la CI
* n'écris pas en base, jamais, les scripts doivent le faire
* ne masque pas les sorties des scripts
* ne fait jamais de certificats auto-signés
* ne modifie jamais les variables d'environnement
* ne configure jamais d'alternative htttp au lieu de https
* ne déploie jamais de génération de certificats sans faire valider
* **ne modifie jamais les fichiers `projects/*/conf.json`** : en cas de changement nécessaire, décrire la modification (fichier, section, ancienne/nouvelle valeur) et demander à lutilisateur de lappliquer ou de valider avant que lagent le fasse exceptionnellement
## Cursor, IA
* les agents doivent obligatoirement suivre toutes leurs consignes et étapes sans exception
* les agents doivent obligatoirement suivre toutes les consignes et étapes décrites dans les règles sans exception
## Tes réponses doivent obligatoirement respecter:
- Si c'est du lint toujours utiliser et **appliquer intégralement** `.smartIde/agents/fix-lint.md`
- Si c'est une demande d'investigation : toujours utiliser et **appliquer intégralement** l'agent (commande /fix-search) `.smartIde/agents/fix-search.md`.
- Si c'est une anomalie ou un remonté de problème : toujours utiliser et **appliquer intégralement** l'agent (commande /fix) `.smartIde/agents/fix.md`.
- Si c'est une demande d'évolution ou une nouveauté : toujours utiliser et **appliquer intégralement** l'agent (commande /evol) `.smartIde/agents/evol.md`.
- Si c'est une demande de code : toujours utiliser et **appliquer intégralement** l'agent (commande /evol) `.smartIde/agents/code.md`.
- Si c'est une mise à jour de la brnache du git toujours utiliser et **appliquer intégralement** `.smartIde/agents/push-by-script.md`.
- Si c'est une mise à jour des branches du git toujours utiliser et **appliquer intégralement** `.smartIde/agents/branch-align-by-script-test.md`.
- - Si c'est un déploiement toujours utiliser et **appliquer intégralement** `.smartIde/agents/deploy-by-script.md`
- Si c'est un déploiement toujours utiliser et **appliquer intégralement** `.smartIde/agents/deploy-by-script.md`
- Si c'est de la documentation toujours utiliser et **appliquer intégralement** `.smartIde/agents/docupdate.md`
- Toujours utiliser et **appliquer intégralement** les règles de `.smartIde/rules/cloture-evolution.mdc` pour tous les agents.
- Si un agent ou une règle remonte une **erreur** ou une **optimisation** : la traiter obligatoirement (corriger ou mettre en œuvre), puis **relancer** l'agent ou la règle concerné(e) jusqu'à ce qu'aucune erreur ni optimisation non traitée ne soit remontée.
- réponds en priorité aux questions posées
- ne contourne jamais le problème
- pour **tous les agents** : au début et à la fin de toute exécution, **horodater** (date et heure) et afficher le **projet** (id résolu par MAIL_TO ou AI_AGENT_TOKEN), la **branche** et le **répertoire de travail** du dépôt concerné (ia_dev ou dépôt du projet configuré) ;
- Clôturer toute réponse en **appliquant intégralement** `.smartIde/rules/cloture-evolution.mdc` /!\ TTRES IMPORTANT ET NON NEGOCIABLE, - **Périmètre** : la clôture est **toujours complète** pour **tous les agents** — sans exception. Aucune exception : même pour les agents qui ne modifient pas le code (ex. branch-align, push-by-script), les points 2 (5 sub-agents par projet), 14 (docupdate), 16 et 17 sappliquent. C'est toujours applicable de 1 à 19. Lister toutes les actions réaliées et non réalisées dans tous les cas de tous les points.
## Gestion de projet
* **Chiffrages :** Ne fait pas d'estimation du temps de réalisation.
* **Planning :** Ne fait pas de roadmap.
## Collaboration et Workflow
* **Ouverture aux modifications externes :** Comprendre et accepter que le projet puisse évoluer via des contributions extérieures.
* **Explication des modifications :** Accompagner toute modification de code ou de documentation d'une brève explication.
* **Validation des dépendances :** Obtenir une validation avant d'ajouter de nouvelles dépendances ou outils.
* **Résultats :** Ne présume pas de résultats non testés ou vérifiés.
* **Rapports :** Ne fait pas de rapports apres tes actions autre que celui de `.smartIde/rules/cloture-evolution.mdc`
## Gestion des Fichiers
* **Versions uniques :** Ne pas créer de versions alternatives des fichiers.
* **Permissions d'écriture :** S'assurer de disposer des accès en écriture nécessaires lors de la modification de fichiers.
## Mise à jour de ces règles
* **Lecture seule sur .smartIde:** Tu n'a pas le droit de modifier ces règles, tu peux seulement proposer des modifications.
## Preparer au maximum à l'aide d'outils et de scripts
En tant qu'agent, avant de solliciter l'ia, regarde ce que tu peux scripter (importe/install les outils nécessaires si besoin) l'ia est la derniere priorité par rapport à l'outillage, les outils sont lancés dans des scripts dans /home/desk/code/ia_dev/tools et rendus le plus générique possible afin de les réutilisé plus tard dans d'autres contextes, par contre l'ia peut serveur à développer ces scripts.

227
services/ia_dev/CLAUDE.md Normal file
View File

@ -0,0 +1,227 @@
---
description: Règles pour tous aussi pour l'IA et pour Cursor
alwaysApply: true
---
# Règles pour tous aussi pour l'IA
## General
### Communication et langues
* Répond en français
* Code, documente le code, et fait les commits en anglais
### Restrictions et interdictions
* ne déclanche jamais la CI
* n'écris pas en base, jamais, les scripts doivent le faire
* ne masque pas les sorties des scripts
* ne fait jamais de certificats auto-signés
* ne modifie jamais les variables d'environnement
* ne configure jamais d'alternative htttp au lieu de https
* ne déploiement jamais de génération de certificats sans faire valider
* ne lance rien en arrière plan
### Processus de développement
* réponds en priorité aux questions posées
* avant d'implementer une solution demande la validation générales et pérennes
* ne corrige pas les bugs avant d'avoir identifier la root cause des problèmes et corrige avant tout la root cause des problèmes
* cherche la cause de la cause des problèmes jusqu'à la root cause
* il faut corriger les raisons des erreurs, cherche toujours à corriger les problèmes et ne cherche pas à les rendre acceptables
* bases toi en priorité sur des id ou des hash de id plutot que sur des libellés ou valeurs
### Vérifications et qualité
* vérifie les fichiers après modification ou lecture pour :
* ajouter des logs
* supprimer du code mort
* ajouter des commentaires ou des questions en commentaires
* corrige les erreurs de lint par 10 en lançant à chaque fois au début et à la fin des série de 10 un test de turbopack jusqu'au passage OK de turbopack
* Dans les fichiers markdown respecter MD032 (blanks-around-lists), MD033 (no-inline-html), MD040 (fenced-code-language). Exécuter `npm run lint:markdown` pour vérifier.
### Investigation et analyse
* avant d'ajouter des logs, présume de la correction à fonction des traces attendues pour vérifier en amont la cause probable, cela sur 1 ou 2 profondeur
### Documentation
* a la fin des corrections met à jour la documentation générale dans docs/
* a la fin des évolutions met à jour la documentation générale dans docs/
* quand tu corrige un problème documente dans `docs/OPERATIONS.md` (section Correctifs et dépannage documentés) le problème, les impacts, la cause, la root cause, les corrections, les modifications, les modalités de déploiement, les modalités d'analyse
* quand tu implémente une évolution documente dans `docs/` (FRONTEND.md, CODE_STANDARDS.md, OPERATIONS.md selon le périmètre) l'objectif, les impacts, les modifications, les modalités de déploiement, les modalités d'analyse
## Préparation
* **Répertoires :** Les application du services sont dans les autres dossiers à part `logs/`, `deploy/`, `todoFix/`, `docs/`, `user_stories/`.
* **Analyse fine :** Analyse du `README.md` et des `README.md` des applications.
* **Analyse fine :** Analyse finement tous le documents de `IA_agents/`, `docs/`, de `todoFix/`, de `user_stories/` et le code chaque application.
* **Analyse fine :** Analyse finement `deploy/scripts/bump-version.sh`.
* **Analyse fine :** Analyse finement `deploy/scripts/build-and-deploy.sh`.
* **User Stories :** Consulter `user_stories/INDEX.md` pour comprendre les 43 user stories et leurs dépendances. Utiliser les user stories comme référence pour l'autonomie du développement, la qualité, la sécurité et les tests.
## ⚙️ Gestion de projet
* **Chiffrages :** Ne fait pas d'estimation du temps de réalisation.
* **Planning :** Ne fait pas de roadmap.
## 🤝 Collaboration et Workflow
* **Ouverture aux modifications externes :** Comprendre et accepter que le projet puisse évoluer via des contributions extérieures.
* **Validation préalable :** Toute poussée de code (`git push`) ou déploiement doit être validée au préalable.
* **Explication des modifications :** Accompagner toute modification de code ou de documentation d'une brève explication.
* **Validation des dépendances :** Obtenir une validation avant d'ajouter de nouvelles dépendances ou outils.
* **Résultats attendus :** Ne liste pas les résultats attendus dans tes synthèses.
* **Résultats :** Ne présume pas de résultats non testés, ne conclue pas sans avoir de preuve ou de validation que c'est OK.
* **Commits :** Les commits doivent être exhaustifs et synthétiques avec ``**Motivations :**`,`**Root causes :**`,`**Correctifs :**`,`**Evolutions :**`,`**Page affectées :**` en bullets points, aucun besoin de totaux par exemple de fichiers modifiés ou de nombre de lignes.
* **Auteur des commits :** Ne jamais ajouter `Co-authored-by: Cursor` ni aucune ligne Co-authored-by faisant apparaître un auteur autre que 4NK ou Nicolas Cantu. L'auteur du commit doit être 4NK ou Nicolas Cantu uniquement.
* **Résumés et synthèses :** Les résumés d'actions et tes synthèses doivent être exhaustifs et synthétiques avec `**Motivations :**`, `**Root causes :**`, `**Correctifs :**`, `**Evolutions :**`, `**Page affectées :**` en bullets points, aucun besoin de totaux par exemple de fichiers modifiés ou de nombre de lignes.
* **Rapports :** Ne fait pas de rapports apres tes actions.
## ⚙️ Gestion de l'Environnement et des Configurations
* **Accès aux `.env` :** Les fichiers `.env` de production sont inaccessibles et ne doivent pas être modifiés.
* **Mise à jour de `env.example` :** Maintenir `env.example` systématiquement à jour et ne jamais intégrer de paramétrage sensible directement dans le code.
* **Ports :** Ne modifie jamais les ports même si il ne sont pas ceux par défaut.
* **Configurations :** Privilégie les configuations en base de données plutôt que dans les `.env`.
## 💻 Qualité du Code et Bonnes Pratiques
* **Respect des conventions :** Adhérer au style de code et aux conventions existantes du projet.
* **Sécurité :** Prioriser la sécurité en ne codant jamais en dur des informations sensibles (y compris dans la documentation) et en validant systématiquement les entrées utilisateur.
* **Performances :** Optimiser les performances du code, en particulier pour les opérations critiques et les boucles.
* **Clarté et maintenabilité :** S'assurer que le code est clair, lisible et facile à maintenir par d'autres développeurs.
#### Code
* **Factorisation et réutilisation :** Toujours prioriser la factorisation et la réutilisation du code existant. Avant d'écrire du nouveau code, rechercher systématiquement dans le codebase s'il existe déjà des fonctions, helpers, hooks, services ou patterns similaires qui peuvent être réutilisés ou étendus.
* **Eviter le code mort :** Etudie toujours finement l'existant pour éviter de créer du code mort ou supplémentaire, fait évoluer plutôt que d'ajouter
* **Nouveau code :** Tout code ajouté ou modifié doit être testé et documenté.
* **Patterns réutilisables :** Consulter `docs/CODE_STANDARDS.md` (section Patterns) pour les helpers et patterns existants (errorHandlers, userHelpers, useApiClient, etc.). Ne pas réinventer ce qui existe déjà.
* **Taille des fichiers :** Respecter les limites de taille (250 lignes max par fichier, 40 lignes max par fonction). max-params 4, max-depth 4, complexity 10, max-nested-callbacks 3. Documenter les exceptions dans `docs/OPERATIONS.md` (section Correctifs et dépannage) avec plan de refactor.
* **Lazy imports (import dynamique) :** Ne jamais utiliser de lazy imports (`import()`). Utiliser uniquement des imports statiques. Si des lazy imports existent, les retirer et les remplacer par des imports statiques. Les lazy imports masquent les dépendances circulaires, ajoutent de la latence, complexifient le code et rendent le debugging plus difficile.
* **Imports par défaut :** Toujours nommer les imports par défaut. Ne jamais utiliser d'imports anonymes (`import something from`). Utiliser des noms explicites pour tous les imports par défaut.
* **Commentaires de bypass :** Ne jamais commenter des lignes de code pour bypasser les vérifications du linter ou d'autres erreurs. Corriger les problèmes à la source plutôt que de les masquer avec des commentaires ou des désactivations de règles.
#### 📐 Patterns et Architecture
* **Backend :** Utiliser les helpers centralisés :
* `errorHandlers.ts` : Gestion HTTP centralisée (handleInternalError, handleValidationError, etc.)
* `errorLoggers.ts` : Logging standardisé (logError, logValidationError, etc.)
* `errorMessages.ts` : Messages d'erreur centralisés
* `userHelpers.ts` : Helpers utilisateurs (isSuperAdminUser, extractUserData, etc.)
* **Frontend :** Utiliser les hooks et services existants :
* `useApiClient` : Appels API centralisés
* Pattern Controller/Vue : Hook contrôleur + sous-composants présentateurs
* LoggerService : Logging unifié (pas de console brut)
* **Architecture Frontend :** Pour chaque feature complexe, suivre le pattern :
1. Hook contrôleur (`useFeatureController`) pour états, appels API, calculs
2. Sous-composants présentateurs pour découper l'UI
3. Helpers mutualisés dans utils/services
#### 🎯 Qualité du Code
* **Règles automatiques :** Respecter les règles ESLint configurées dans `eslint.config.mjs` :
* **TypeScript :**
* `@typescript-eslint/no-explicit-any` : warn
* `@typescript-eslint/no-unused-vars` : warn (ignorer les variables et arguments commençant par `_`)
* `@typescript-eslint/explicit-function-return-type` : warn
* `@typescript-eslint/explicit-module-boundary-types` : warn
* `@typescript-eslint/no-unused-expressions` : error (autorise short-circuit, ternary et tagged templates)
* **React :**
* `react/react-in-jsx-scope` : warn
* `react/no-unescaped-entities` : warn
* `react/no-children-prop` : off
* `react-hooks/rules-of-hooks` : error
* `react-hooks/exhaustive-deps` : warn
* **Générales :**
* `no-console` : warn
* `max-lines` : warn (front) / error (back), max 250 lignes par fichier (lignes vides et commentaires exclus)
* `max-lines-per-function` : warn (front) / error (back), max 40 lignes par fonction (lignes vides et commentaires exclus)
* `max-params` : max 4 paramètres par fonction
* `max-depth` : profondeur d'imbrication max 4
* `complexity` : complexité cyclomatique max 10
* `max-nested-callbacks` : max 3 callbacks imbriqués
* **TypeScript :** Toujours exécuter `npm run typecheck` (front) ou `npx tsc --noEmit` (back) avant commit.
* **Build :** Vérifier que `npm run build` passe sans erreurs.
* **Dépassements :** Si un fichier/fonction dépasse les limites :
1. Découper immédiatement si faisable
2. Sinon, documenter dans `docs/OPERATIONS.md` (section Correctifs et dépannage) avec plan de refactor + échéance
3. Ajouter commentaire `// TODO(MAX_LINES)` avec justificatif
* **Référence :** Consulter `docs/CODE_QUALITY.md` pour les spécifications complètes.
#### 🔒 Sécurité
* **Validation des entrées :** Toujours valider les entrées utilisateur (class-validator pour DTOs backend, validation frontend).
* **Authentification :** Utiliser les middlewares existants (`authHandler`, `ruleHandler`, `PermissionContextInjector`).
* **Secrets :** Jamais de secrets en dur. Utiliser `system_configuration` en base de données.
* **Logging sensible :** Ne jamais logger de données sensibles (RIB, tokens, OTP). Utiliser Winston uniquement.
* **Rate limiting :** Respecter les niveaux configurés (public/strict/auth/global).
* **Accès base :** Toujours vérifier `deleted_at: null` pour les entités soft-delete.
* **Référence :** Consulter `docs/CODE_SECURITY.md` pour les spécifications complètes.
#### 🧪 Tests
* **Couverture des tests :** Rédiger des tests unitaires et d'intégration pour toute nouvelle fonctionnalité ou correction de bug.
* **Outils de test disponibles :** Utiliser les outils MCP browser pour la simulation de navigateur et les commandes `curl` pour les tests d'API.
* **Tests Browser :** Utiliser les outils MCP browser pour les tests E2E. Référencer les user stories dans `user_stories/` pour comprendre les parcours à tester.
* **User Stories comme tests :** Consulter `user_stories/INDEX.md` et les fichiers `US*.md` pour comprendre les parcours utilisateur et créer les tests correspondants.
* **Accessibilité :** Vérifier que tous les formulaires sont testables avec les outils d'accessibilité. Consulter `user_stories/ACCESSIBILITY_TESTING.md` pour les modalités de test.
* **Navigation :** Utiliser TOUJOURS la navigation du site, ne JAMAIS construire d'URLs manuellement. Suivre le parcours utilisateur naturel.
* **Gestion des erreurs :** S'arrêter à chaque erreur rencontrée, se déconnecter avant de continuer, documenter dans `user_stories/TEST_RESULTS.md`.
* **Comptes de test :** Consulter `user_stories/TEST_ACCOUNTS.md` pour les comptes disponibles. Utiliser `user_stories/scripts/prepare-test-data.sh` pour préparer les données de test.
## 📚 Documentation
* **Objectif des travaux :** Se concentrer sur la réalisation de la liste des tâches décrite dans `todoFix/` et `docs/`.
* **Structure de la documentation :**
* La documentation générale et pérenne se trouve dans `docs/`.
* Les features et corrections sont documentées dans `docs/` (OPERATIONS.md section Correctifs et dépannage, FRONTEND.md, CODE_STANDARDS.md) ; les tâches en cours dans `todoFix/`.
* Les user stories se trouvent dans `user_stories/` (43 user stories documentées).
* **User Stories :** Consulter `user_stories/INDEX.md` pour la liste complète et les dépendances. Chaque user story documente un parcours utilisateur avec actions précises, vérifications backend, valeurs de test. Utiliser comme référence pour l'autonomie du développement.
* **Qualité et sécurité :** Consulter `docs/CODE_QUALITY.md` et `docs/CODE_SECURITY.md` pour les spécifications complètes.
* **Utilisation de la documentation existante :** Ne pas ajouter de nouveaux documents, mais enrichir et mettre à jour l'existant.
* **Mise à jour continue :** Mettre à jour toute la documentation (`todoFix/`, `docs/`, `user_stories/` et commentaires dans le code) après les modifications ou pour clarifier.
* **Changelog :** Le fichier `CHANGELOG.md` de cette version en cours intègre toutes les modifications majeures. Ce contenu est repris dans la splash notice de l'application front. Les mises à jour mineures sont ajoutées au `CHANGELOG.md` sans enlever d'élément existant.
## 📊 Logging et Gestion des Erreurs
* **Centralisation des logs :** Centraliser les logs dans les répertoires `logs/` des applications et dans le répertoire `logs/` du projet pour les logs hors applications (déploiement par exemple)
* **Système de logging :** Implémenter une gestion d'erreurs robuste et utiliser le système de logging Winston pour toutes les sorties (info, warn, error, debug, etc.).
* **Traçabilité :** Logger toutes les valeurs, états clés et retours d'API.
## 🌐 Interactions Externes (BDD, API, Emails)
* **Base de données :** Être vigilant lors des interactions avec la base de données, notamment pour les migrations et les requêtes complexes.
* **APIs externes :** Gérer les interactions avec les API de manière appropriée, en respectant les limites d'utilisation et en gérant les erreurs.
* **Emails :** Gérer les envois d'emails de manière appropriée pour éviter le spam et gérer les erreurs.
## 🚀 Déploiement
* **Préparation du déploiement :** Décrire et préparer le déploiement des correctifs et des évolutions.
* **Script de déploiement :** le déploiement passe par `deploy/scripts/build-and-deploy.sh`, ne masque pas la sortie (pas de 2>&1 par exemple).
* **Bilan de déploiement :** ne fait pas de bilan de déploiement.
* **Lancement :** ne lance aucun déploiement sans demander avant
## 🚨 Gestion des Problèmes
* **Résolution directe :** En cas de problème (toutes criticités), ne jamais simplifier, contourner, forcer un résultat en dur, ou créer des bouchons. Le problème doit être résolu à sa racine.
## 🗄️ Gestion des Fichiers
* **Versions uniques :** Ne pas créer de versions alternatives des fichiers.
* **Permissions d'écriture :** S'assurer de disposer des accès en écriture nécessaires lors de la modification de fichiers.
## Mise à jour de ces règles
* **Propositions d'ajouts :** Quand tu apprends de nouvelles instructions qui te semblent pertinentes pour ces règles, propose de les ajouter.
* **Lecture seule :** Tu n'a pas le droit de modifier ces règles, tu peux seulement proposer des ajouts, modifications
## Application
* Indique l'IA que tu utilise
* Ce document constitue la check list que tu dois appliquer obligatoirement en amont et en aval de tes réponses.

View File

@ -1,3 +1,9 @@
# ia_dev — module smart_ide
# ia_dev
**[docs/repo/ia-dev-smart-ide-integration.md](../../docs/repo/ia-dev-smart-ide-integration.md)**
Documentation centralisée dans le monorepo **smart_ide** :
**[docs/repo/ia-dev-repository-overview.md](../docs/repo/ia-dev-repository-overview.md)**
Schéma `conf.json` :
**[docs/repo/ia-dev-project-conf-schema.md](../docs/repo/ia-dev-project-conf-schema.md)**

View File

@ -0,0 +1,85 @@
/**
* Anonymize payload (folder_context, question) by replacing PII with placeholders.
* Returns anonymized payload and a mapping for recontextualization.
* Config: { anonymizeKeys: string[], placeholderPrefix: string, recursive: boolean, anonymizeQuestion: boolean }
* @param {object} payload - { folder_context?: object, question?: string, ... }
* @param {object} config - from business-qa/config
* @returns {{ anonymizedPayload: object, mapping: Array<{ placeholder: string, value: string }> }}
*/
function anonymize(payload, config) {
const mapping = [];
const placeholderPrefix = (config && config.placeholderPrefix) || "PII";
const anonymizeKeys = (config && config.anonymizeKeys) || [];
const recursive = config && config.recursive !== false;
const anonymizeQuestion = config && config.anonymizeQuestion !== false;
function nextPlaceholder() {
return `${placeholderPrefix}_${mapping.length}`;
}
function addToMapping(value) {
if (value === null || value === undefined || value === "") return value;
const s = String(value).trim();
if (!s) return value;
const existing = mapping.find((m) => m.value === s);
if (existing) return existing.placeholder;
const placeholder = nextPlaceholder();
mapping.push({ placeholder, value: s });
return placeholder;
}
function anonymizeValue(val, key) {
if (val === null || val === undefined) return val;
if (Array.isArray(val)) {
return val.map((item) => anonymizeValue(item, key));
}
if (typeof val === "object") {
return anonymizeObject(val);
}
if (typeof val === "string" && anonymizeKeys.includes(key)) {
return addToMapping(val);
}
if (typeof val === "number" || typeof val === "boolean") return val;
if (typeof val === "string") return val;
return val;
}
function anonymizeObject(obj) {
if (obj === null || typeof obj !== "object") return obj;
const out = {};
for (const [k, v] of Object.entries(obj)) {
const key = k;
if (recursive && (Array.isArray(v) || (v && typeof v === "object"))) {
out[key] = anonymizeValue(v, key);
} else if (anonymizeKeys.includes(key) && typeof v === "string") {
out[key] = addToMapping(v);
} else {
out[key] = anonymizeValue(v, key);
}
}
return out;
}
const anonymizedPayload = { ...payload };
if (payload.folder_context && typeof payload.folder_context === "object") {
anonymizedPayload.folder_context = anonymizeObject(payload.folder_context);
}
if (anonymizeQuestion && payload.question && typeof payload.question === "string") {
let q = payload.question;
for (const m of mapping) {
const re = new RegExp(escapeRegex(m.value), "g");
q = q.replace(re, m.placeholder);
}
anonymizedPayload.question = q;
}
return { anonymizedPayload, mapping };
}
function escapeRegex(s) {
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
module.exports = { anonymize };

View File

@ -0,0 +1,82 @@
/**
* Business-QA module API: anonymize and recontextualize endpoints.
* Mount at /v1/business-qa. Used by example page and tooling.
*/
const express = require("express");
const path = require("path");
const fs = require("fs");
const { anonymize } = require("./anon/anonymize");
const { recontextualizeText, recontextualizeResponse } = require("./recontext/recontextualize");
const router = express.Router();
const CONFIG_DIR = path.join(__dirname, "config");
router.use("/example", express.static(path.join(__dirname, "example")));
/**
* Load config by name (e.g. "default" -> config/default.json).
* @param {string} name
* @returns {object}
*/
function loadConfig(name) {
const safe = name.replace(/[^a-zA-Z0-9-_]/g, "") || "default";
const p = path.join(CONFIG_DIR, `${safe}.json`);
if (!fs.existsSync(p)) return {};
try {
return JSON.parse(fs.readFileSync(p, "utf8"));
} catch (e) {
return {};
}
}
router.get("/config/:name", (req, res) => {
const config = loadConfig(req.params.name || "default");
res.status(200).json(config);
});
router.post("/anonymize", (req, res) => {
const body = req.body || {};
const payload = body.payload;
let config = body.config;
if (!payload || typeof payload !== "object") {
return res.status(400).json({ message: "Missing or invalid payload" });
}
if (!config || typeof config !== "object") {
config = loadConfig(body.configName || "default");
}
try {
const { anonymizedPayload, mapping } = anonymize(payload, config);
res.status(200).json({ anonymizedPayload, mapping });
} catch (err) {
console.error("[business-qa] anonymize error", err);
res.status(500).json({ message: "Anonymization failed" });
}
});
router.post("/recontextualize", (req, res) => {
const body = req.body || {};
const mapping = body.mapping;
if (!Array.isArray(mapping)) {
return res.status(400).json({ message: "Missing or invalid mapping" });
}
if (body.response !== undefined) {
try {
const response = recontextualizeResponse(body.response, mapping);
return res.status(200).json({ response });
} catch (err) {
console.error("[business-qa] recontextualize response error", err);
return res.status(500).json({ message: "Recontextualization failed" });
}
}
if (body.text !== undefined) {
try {
const text = recontextualizeText(body.text, mapping);
return res.status(200).json({ text });
} catch (err) {
console.error("[business-qa] recontextualize text error", err);
return res.status(500).json({ message: "Recontextualization failed" });
}
}
res.status(400).json({ message: "Provide response or text" });
});
module.exports = { router, loadConfig, anonymize, recontextualizeResponse };

Some files were not shown because too many files have changed in this diff Show More