iArt.ai
AI 모션 그래픽 소프트웨어, 누구나 사용할 수 있는 After Effects 대안, 텍스트 프롬프트로 몇 분 안에 애니메이션·설명 영상 제작
모바일 기술 감시: React Native, TypeScript, iOS, Android, 내장 AI. 공식 소스에 증거가 없으면 차단되지 않음
Veille technologique mobile : React Native, TypeScript, iOS, Android et IA embarquée. Rien n'est bloquant sans preuve retrouvée dans la source officielle.
미디어TypeScript · JavaScriptGitHub @CEDRIC-code1982온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Veille technologique mobile
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Veille technologique automatisée sur React Native, TypeScript, iOS et Android : versions d'OS, nouvelles fonctionnalités, exécution en arrière-plan, Bluetooth/BLE, matériel. Collecte quotidienne, classification par un modèle, vérification déterministe de toute information critique, publication sur un site statique consultable depuis un téléphone. Aucune relecture humaine dans la boucle. C'est précisément pour ça que la règle de confiance ci-dessous existe. Site : https://cedric-code1982.github.io/Veille-mobile/ — installable en PWA et consultable hors ligne.README 전문 보기 ↗
Veille technologique automatisée sur React Native, TypeScript, iOS et Android : versions d'OS, nouvelles fonctionnalités, exécution en arrière-plan, Bluetooth/BLE, matériel. Collecte quotidienne, classification par un modèle, vérification déterministe de toute information critique, publication sur un site statique consultable depuis un téléphone.
Aucune relecture humaine dans la boucle. C'est précisément pour ça que la règle de confiance ci-dessous existe.
Site : https://cedric-code1982.github.io/Veille-mobile/ — installable en PWA et consultable hors ligne.
Un item ne peut porter criticality: "blocking" que si les trois conditions
sont réunies :
sourceUrl appartient à un domaine de config/official-domains.json
(première partie uniquement) ;evidenceQuote non vide ;verify a refetché la page et retrouvé cette citation dans
son contenu, sur texte normalisé (casse, espaces multiples, entités HTML,
ponctuation typographique).Si une seule condition échoue, l'item est automatiquement rétrogradé à
impacting au maximum, avec trustLevel: "unverified". Un échec de
vérification n'est pas une erreur : c'est un déclassement normal, loggé en
WARN, qui ne fait pas échouer le run.
Un blog tiers ne peut jamais produire un blocking, même en citant
correctement sa source.
Les trois niveaux de confiance :
trustLevel | Signification |
|---|---|
verified | citation retrouvée dans la source officielle |
reported | domaine officiel, mais citation non retrouvée (ou absente) |
unverified | proposé par le modèle, rien ne le confirme |
Le site affiche le badge unverified de façon volontairement voyante.
Quatre étapes indépendantes qui ne communiquent que par fichiers. Aucune ne connaît l'implémentation des autres.
collect → classify → verify → publish
(réseau, (LLM, (réseau, (git, issues,
0 LLM) 0 réseau 0 LLM) 0 LLM)
hors API)
| Étape | Entrée | Sortie | Règle |
|---|---|---|---|
collect | config/feeds.yaml | data/raw/YYYY-MM-DD.json | n'appelle jamais le LLM |
classify | le fichier ci-dessus | data/raw/YYYY-MM-DD.classified.json | ne décide jamais de la publication |
verify | le fichier ci-dessus | data/raw/YYYY-MM-DD.verified.json | ne fait jamais confiance au LLM |
publish | le fichier ci-dessus | data/items/, digest/, data/index.json, issues | n'appelle jamais le LLM |
src/domain/ ne dépend d'aucune bibliothèque externe, pas même de
node:crypto : types purs et fonctions pures. Le temps arrive par un port
Clock, le hachage vit dans src/shared/hash.ts.src/data/ contient les implémentations (RSS/Atom, scraping, API Anthropic,
API GitHub).data/raw/ n'est pas versionné : c'est là que vivent les extraits
d'articles, et le contenu tiers n'a rien à faire dans le dépôt. Seuls l'URL,
un résumé reformulé et la citation-preuve sont publiés.npm ci
npm run check:feeds # confronte chaque source à un vrai fetch
npm test
npm run lint && npm run typecheck
Le pipeline en local, chemin routine, sans aucune clé API :
npm run collect
npm run classify:request # écrit les instructions de classification
# # ... un modèle écrit le fichier de propositions ...
npm run classify:file # valide ces propositions par Zod
npm run verify
npm run publish
Chemin API, si un jour tu poses une clé :
ANTHROPIC_API_KEY=... npm run classify
Le site en local, servi exactement comme GitHub Pages le servira :
npm run site:serve
Le moteur n'est pas un cron GitHub : c'est une routine planifiée locale, une tâche Claude qui tourne chaque matin. Elle est elle-même le modèle : au lieu d'appeler l'API Messages, elle lit un fichier d'instructions et écrit un fichier de propositions.
routine ──► npm run collect
──► npm run classify:request → data/raw/<jour>.request.md
──► elle classe, et écrit data/raw/<jour>.proposals.json
──► npm run classify:file → validé par Zod, comme une réponse d'API
──► npm run verify → refetch et confrontation des citations
──► npm run publish
──► git commit && git push → déclenche deploy.yml
Trois propriétés de ce découpage :
verify
refetche les sources exactement pareil. Un blocking qu'elle propose sans
citation retrouvable est rétrogradé comme n'importe quel autre.git push quotidien constitue une activité sur le dépôt, ce qui
neutralise le piège des 60 jours décrit plus bas.Le prompt de la routine vit dans docs/routine-prompt.md, versionné et scanné
comme le reste du dépôt. La tâche planifiée ne fait que pointer vers ce fichier,
donc elle ne peut pas dériver du code.
Tout le travail shell est regroupé dans scripts/routine-prepare.sh et
scripts/routine-finish.sh. Ce n'est pas cosmétique : une routine qui tourne
sans surveillance ne doit demander aucune autorisation, et deux scripts
demandent une permission au lieu d'une par commande. Pour qu'elle tourne
réellement sans interaction, il faut une règle dans ~/.claude/settings.json :
"Bash(bash /chemin/vers/Veille-mobile/scripts/*)",
"Read(//chemin/vers/Veille-mobile/**)"
plus le dépôt dans permissions.additionalDirectories, sans quoi la lecture du
fichier d'instructions déclenche une demande, la session planifiée n'ayant pas
ce dépôt pour répertoire de travail.
Limite à connaître : une tâche planifiée ne tourne que si l'application est ouverte. Si elle était fermée à l'heure prévue, le run part au lancement suivant. C'est précisément ce que le watchdog ci-dessous surveille.
collect.yml sert de filet. Il tourne chaque jour à 12:17 UTC, après la fenêtre
du matin de la routine : si celle-ci a fait le travail, ce run ne trouve rien de
neuf et ne committe rien. Sinon il collecte quand même, en publiant des items
sans résumé, que la routine reclassera au passage suivant puisqu'un item sans
résumé est volontairement exclu du jeu des items connus.
Ce filet n'est pas théorique : une tâche planifiée ne s'exécute que si l'application est ouverte, et une interruption de dix jours l'a démontré. Le watchdog l'a bien signalée, mais la veille était à l'arrêt pendant ce temps.
Les notifications d'issue ont besoin d'un jeton de dépôt. Sur une machine
personnelle il n'y en a pas dans l'environnement, donc routine-finish.sh en
demande un à la session gh existante. Sans gh, le run réussit quand même :
le notifieur reste simplement inerte.
config/feeds.yaml : - name: Nom lisible de la source
url: https://exemple.invalid/feed.xml
type: rss # rss | atom | scrape
domain: exemple.invalid
categories: [android, background]
official: true # l'éditeur publie sur son propre produit
maxAgeDays: 21 # seuil de silence
npm run check:feeds. Si l'URL ne répond pas, la retirer plutôt
que d'inventer une URL plausible. C'est la règle du projet.blocking, ajouter son domaine à
config/official-domains.json. official: true dans feeds.yaml ne sert
qu'à départager les doublons, pas à autoriser un blocking.Précisions sur les champs :
categories doit utiliser les valeurs de src/domain/entities/Category.ts :
react-native, typescript, ios, android, background, ble,
hardware, tooling, policy, os-release, nfc, ai, ai-models,
on-device-ai, practices.
maxAgeDays s'applique à l'entrée la plus récente pour rss/atom, et
à la dernière lecture réussie pour scrape : une page de documentation
qui ne change pas est normale, un flux figé ne l'est pas.
type: scrape est destiné aux pages sans flux. Leur identité est le hash de
leur zone principale : un nouvel item apparaît quand, et seulement quand, le
contenu change réellement.
excerptAnchor (optionnel, sur un scrape) fait démarrer le texte retenu au
premier endroit où le motif correspond, au lieu du début de la page :
excerptAnchor: 'Model status' # le tableau, pas la prose qui le précède
Une page de documentation enterre souvent sa charge utile sous un long préambule. Les tableaux de dépréciation, qui portent les dates de retrait, arrivaient après le plafond de l'extrait : le classifieur ne les lisait jamais. L'ancre réduit aussi le hash d'identité, donc un nouvel item n'apparaît que quand la section ancrée change, pas quand une phrase du préambule est reformulée. Un motif illisible ou introuvable garde la page entière : une ancre cassée ne doit pas vider une source.
titlePattern (optionnel) ne garde que les entrées dont le titre correspond.
Certains flux officiels annoncent toutes les plateformes de l'éditeur ; sans
ce filtre elles noient le signal et consomment le budget de classification.
Un motif illisible ne vide pas la source : il est ignoré.
follow (optionnel, sur un scrape) lit une page d'index, y découvre des
clés de version, garde les plus élevées et scrape leurs pages :
follow:
linkPattern: '^/about/versions/(\d+)$' # une seule capture, numérique
urlTemplate: /about/versions/{key}/behavior-changes-all
limit: 2
C'est ce qui évite d'écrire un numéro de version en dur, lequel ferait silencieusement surveiller une version périmée.
La section « Systèmes » du site regroupe les items portant la catégorie
os-release : les dernières versions publiées et les pages de changements de
comportement. Les mêmes items restent dans leur section de criticité, cette vue
n'est qu'un index.
Le comparatif avec la version remplacée vient du mécanisme follow : la source
« Android Behavior Changes » découvre les deux versions les plus récentes depuis
l'index officiel et scrape leurs deux pages. On obtient donc en permanence la
version courante et celle qu'elle remplace, sans qu'aucun numéro ne soit
écrit nulle part. Quand une nouvelle version sort, le suivi bascule tout seul.
Côté Apple, il n'existe pas d'équivalent exploitable : aucune page officielle n'indexe les versions de façon à ce qu'on puisse en découvrir les clés. Le suivi repose donc sur le flux des releases développeur, dont la charge utile est le titre (version et build), et sur la page des mises à jour de sécurité.
Les pages developer.apple.com/documentation/* sont des applications
JavaScript qui ne rendent rien à un client HTTP — mais le suffixe .md renvoie
la même page en markdown, servie telle quelle. Vérifié sur foundationmodels,
corebluetooth et corenfc : c'est un mécanisme général du site. Toute page de
documentation Apple est donc collectable, à condition d'ajouter .md à son URL.
Le prompt impose au modèle, pour tout item os-release, de dire ce que la
version change par rapport à celle qu'elle remplace, et uniquement si
l'extrait l'énonce : jamais de comparaison reconstruite.
La carte « IA » regroupe les items portant la catégorie ai, et pose une
deuxième question comme les cartes Apple et Android, parce que deux veilles très
différentes cohabitent sous le même mot.
Modèles & assistants (ai-models) : l'écosystème lui-même. Les modèles qui
sortent, ceux qui sont retirés et à quelle date, les assistants de code bâtis
dessus, et la façon de s'en servir — invites, agents, outils, évaluation.
Anthropic, OpenAI, Google, Mistral, Meta, GitHub Copilot et Visual Studio Code
y sont suivis chez l'éditeur, plus une seule source non officielle assumée.
Pratiques (practices) : les articles de méthode plutôt que les annonces —
un schéma, un piège, une façon de tester ou de mesurer. La catégorie s'ajoute
aux autres, elle ne les remplace pas, et une note de version n'en fait jamais
partie même quand elle explique ce qu'elle change.
Sur l'appareil (on-device-ai) : faire tourner un modèle dans une
application mobile. Le framework Foundation Models d'Apple, Gemini Nano et ML
Kit côté Android, et react-native-executorch qui relie les deux à React
Native.
Les pages de dépréciation de modèles sont les seules du premier lot à pouvoir
porter un blocking, et c'est voulu : elles énoncent des dates de retrait
fermes, ce qui correspond exactement à la définition d'une contrainte externe
datée. Leurs domaines sont donc dans config/official-domains.json, et la règle
de preuve s'applique comme partout ailleurs — la citation doit être retrouvée
dans la page refetchée.
Deux sources ont été écartées après lecture, pour que personne ne les rajoute par réflexe :
openai.com/news/rss.xml : 1 243 entrées, 71 sur trente jours, en majorité de
la communication d'entreprise. Le changelog de la plateforme dit la même chose
côté développeur.huggingface.co/blog/feed.xml : même problème de volume, sans le filtre de
l'officiel.Une veille qui s'arrête sans le dire est pire que pas de veille : elle donne
l'impression d'être informé. Deux symptômes ouvrent une issue
[VEILLE] Flux muet :
maxAgeDays ;VEILLE_PIPELINE_SILENCE_DAYS).Un troisième garde-fou surveille le pipeline lui-même. watchdog.yml tourne
chaque jour sur GitHub Actions, ne collecte rien, ne publie rien, n'a besoin
d'aucune clé : il lit data/index.json et ouvre une issue
[VEILLE] Pipeline silencieux si la dernière collecte date de plus de trois
jours (VEILLE_HEARTBEAT_SILENCE_DAYS). C'est ce qui rattrape une machine
éteinte, une routine désactivée ou un git push qui échoue.
C'est, avec un blocking vérifié, la seule notification autorisée à déranger.
L'idempotence vient d'un marqueur <!-- veille-fingerprint: ... --> dans le
corps de l'issue : un run quotidien ne réouvre pas la même issue. La clé d'un
flux muet mélange la semaine ISO et l'ensemble trié des sources silencieuses,
donc un silence qui dure reste silencieux, mais une nouvelle source muette
ouvre bien une issue.
GitHub désactive automatiquement les workflows planifiés d'un dépôt public après 60 jours sans activité sur le dépôt, et il faut les réactiver à la main (Actions → le workflow → Enable workflow). C'est documenté dans Events that trigger workflows.
C'est le pire scénario possible ici : le workflow ne tourne plus, donc la détection de flux muet ne tourne pas non plus, donc le silence est invisible. Aucun mécanisme interne au dépôt ne peut rattraper ça.
La parade est déjà en place, et elle est externe au dépôt : la routine quotidienne pousse un commit de données, ce qui constitue une activité sur le dépôt et remet le compteur à zéro bien avant les 60 jours. Le watchdog reste donc actif tant que la routine fonctionne.
L'enchaînement est cohérent : si la routine s'arrête, le watchdog ouvre une issue en trois jours, très largement avant que les 60 jours ne le désactivent à son tour. Si les deux s'arrêtent en même temps, il faut un déclenchement manuel :
gh workflow run watchdog.yml --repo <owner>/Veille-mobile
GitHub recommande par ailleurs d'éviter le début d'heure pour les cron, les
files d'attente y étant saturées et des jobs pouvant être abandonnés. Le
workflow tourne donc à 37 4 * * *.
GitHub documente qu'un événement déclenché avec le GITHUB_TOKEN ne crée
aucun run de workflow, pour éviter les récursions. Autrement dit, le commit de
données poussé par collect.yml ne déclenche pas deploy.yml, alors que le même
commit poussé par la routine depuis ta machine, avec ta clé, le déclenche
normalement.
collect.yml termine donc par un gh workflow run deploy.yml explicite, et
seulement s'il a réellement poussé quelque chose : workflow_dispatch est la
seule exception documentée à cette règle et fonctionne avec le jeton par défaut.
| Secret | Rôle | Sans lui |
|---|---|---|
FORBIDDEN_TERMS | filet de confidentialité en CI | deploy refuse de publier, et collect.yml refuse de committer |
ANTHROPIC_API_KEY | optionnel : chemin API au lieu de la routine | rien, la routine ne l'utilise pas |
gh secret set FORBIDDEN_TERMS --repo <owner>/Veille-mobile
FORBIDDEN_TERMS contient un terme par ligne, mêmes règles que
forbidden-terms.local.txt.
Le dépôt est public. Aucun contexte professionnel n'y apparaît.
npm run check:privacy échoue si un motif interdit est trouvé dans les
fichiers indexés, les fichiers non ignorés à un git add près, tous les
messages de commit et tous les noms de branches. La correspondance est
insensible à la casse et tolérante aux séparateurs : un seul terme
ExempleEmployeur attrape aussi exemple-employeur, exemple_employeur et
Exemple Employeur.forbidden-terms.local.txt (gitignoré, voir
forbidden-terms.local.txt.example) ou de $FORBIDDEN_TERMS. Avec
--require-terms, l'absence de liste est une erreur : c'est ce que la CI
utilise.pre-commit (.githooks/pre-commit, câblé par npm ci) lance le
scan à chaque commit local.impactedProjects ne contient que des codes opaques (proj-a, …), calculés
depuis config/project-profiles.json. Le modèle n'est jamais interrogé
là-dessus : il ne sait pas que ces projets existent.projects.local.json, gitignoré. Le
site tente de le charger et échoue silencieusement : sans lui, il affiche les
codes.| Variable | Défaut | Effet |
|---|---|---|
ANTHROPIC_MODEL | claude-haiku-4-5-20251001 | modèle de classification, identifiant épinglé |
MAX_ITEMS_PER_RUN | 60 | plafond de coût par run |
MAX_ITEMS_PER_SOURCE | 12 | plafond par source dans un même run |
VEILLE_LLM_BATCH_SIZE | 10 | items par appel API |
VEILLE_MAX_ITEM_AGE_DAYS | 30 | fenêtre de fraîcheur à la collecte |
VEILLE_VERIFY_CONCURRENCY | 4 | refetchs simultanés |
VEILLE_PIPELINE_SILENCE_DAYS | 14 | seuil de silence du pipeline, à la publication |
VEILLE_HEARTBEAT_SILENCE_DAYS | 3 | seuil de silence pour le watchdog |
VEILLE_HTTP_TIMEOUT_MS | 20000 | timeout HTTP |
VEILLE_USER_AGENT | veille-mobile-bot | User-Agent des requêtes |
VEILLE_PREVIEW_PORT | 8099 | port de npm run site:serve |
LOG_LEVEL | INFO | DEBUG | INFO | WARN | ERROR |
MAX_ITEMS_PER_SOURCE n'écarte rien : ce qui dépasse le plafond passe derrière
toutes les autres sources et sera classé s'il reste du budget. C'est ce qui
empêche une source qui publie tous les jours — les versions d'un outil, par
exemple — d'avaler le budget d'une matinée où une règle de store a changé.
Les items écartés par MAX_ITEMS_PER_RUN sont simplement recollectés le
lendemain : le retard se résorbe seul.
Même mécanisme pour la qualité : un item publié sans résumé n'a jamais été réellement classé (modèle en échec, run sans modèle, ou plafond atteint). Il est volontairement exclu du jeu des items connus, donc recollecté et reclassé au run suivant, et la version améliorée remplace la version stockée. Un item dégradé ne reste pas dégradé.
Tous les scripts, sans exception :
[LEVEL][FileName][functionName][line][HH:mm:ss] message
Un log ERROR inclut toujours l'objet erreur complet en second argument.
maxAgeDays, pas immédiatement.classify:request et classify:file doivent voir le même
MAX_ITEMS_PER_RUN. S'ils divergent, les items non couverts par le fichier
de propositions sont dégradés en background / unverified : pas une perte
de données, mais une perte de qualité silencieuse.