samykabu/delegate-task

Délègue une tâche à un agent CLI externe — Claude Code, OpenAI Codex, OpenCode, GitHub Copilot ou Pi — et renvoie un résultat normalisé avec statut (succès / échec / abandonné), résumé, modifications sur le disque mesurées via git, et consommation totale de tokens en entrée et sortie.

Qu'est-ce que delegate-task ?

Cette compétence permet de déléguer une tâche à un agent CLI externe (Claude Code, OpenAI Codex, OpenCode, GitHub Copilot ou Pi) en arrière-plan, sans bloquer le processus appelant. Elle fournit un résultat normalisé contenant le statut (succès, échec ou abandonné), un résumé textuel, la liste des fichiers modifiés dans le dépôt git, et la consommation totale de tokens en entrée et sortie. Le pilote `delegate.mjs` (Node ≥ 18, sans dépendances) expose les commandes `start`, `collect`, `status`, `list`, `prune` et `doctor`. Il gère automatiquement les délais d'attente, la détection des modifications via git (avec alerte en cas de déplacement de HEAD), le sandboxing partiel via le flag `--sandbox`, et la reprise de session avec `--resume`. Une attention particulière est portée à la sécurité : les artefacts de run sont chiffrés avec des permissions restrictives, et les variables d'environnement sont masquées dans les logs. La compétence est conçue pour être utilisée par des agents IA comme Claude Code, Cursor ou Codex, via leur système de skills ou plugins.

Compatible avec✓Claude Code✓Codex CLI~Cursor✓OpenCode
npx skills add https://github.com/samykabu/sanduq-skills/tree/HEAD/skills/agent-tools/skills/delegate-task

Installed? Explore more Recherche et analyse de données skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Déléguer une tâche à un autre agent CLI

Exécute une tâche sur un agent CLI externe en arrière-plan et renvoie un résultat normalisé.

Pilote : delegate.mjs, dans le propre répertoire de cette compétence (Node ≥ 18, aucune dépendance). Le comportement est défini par trois contrats dans contracts/ — lisez-les avant de modifier le pilote.

start renvoie immédiatement un run_id ; collect récupère le résultat. Rien ne vous bloque.

Résoudre d'abord le pilote et le répertoire des runs

Là où cette compétence est installée décide où se trouve delegate.mjs, et les artefacts de run se placent par défaut à côté du pilote. Définissez les deux une fois par session, puis utilisez $DELEGATE dans chaque commande ci-dessous :

# Installation du plugin Claude Code (agent-tools@sanduq)
DELEGATE="$CLAUDE_PLUGIN_ROOT/skills/delegate-task/delegate.mjs"

# Installation via npx skills, ou copie commitée dans le dépôt
DELEGATE=".claude/skills/delegate-task/delegate.mjs"

# Conserver les artefacts de run dans le projet en cours, pas à côté du pilote
export DELEGATE_RUNS_DIR="$PWD/.delegate/runs"

DELEGATE_RUNS_DIR est obligatoire pour une installation via plugin : sans lui, les artefacts de chaque projet s'accumulent dans le répertoire partagé du plugin, et ils contiennent le texte de votre tâche et la sortie brute du harnais. Ajoutez .delegate/ au .gitignore du projet. Chaque commande qui touche un run — start, status, collect, list, prune — doit voir la même valeur.

Vérifier d'abord ce qui est disponible

node "$DELEGATE" doctor

doctor sonde la version de chaque CLI, ce qui distingue non installé de installé mais cassé — et imprime ce que --sandbox demande réellement à chacun.

Harnaisidniveaureprisedemande --sandbox
Claude Codeclaudevérifiévérifié--permission-mode plan
OpenAI Codexcodexvérifiévérifié-s read-only (imposé par la CLI)
OpenCodeopencodevérifiévérifié--agent plan
GitHub Copilotcopilotexpérimentalexpérimental--mode plan
Pipiexpérimentalexpérimental--no-approve --tools read,grep,find,ls

Préférez claude, codex, ou opencode.

Lancer une délégation

node "$DELEGATE" start \
  --harness codex \
  --cwd /chemin/vers/espace-de-travail \
  --timeout 600 \
  --task "Ajouter une validation d'entrée à parse_config() et un test couvrant le chemin d'erreur."

Affiche {"run_id": "codex-…", "state": "running", ...} et se termine. Ensuite :

node "$DELEGATE" collect codex-… --wait 300

--wait N interroge jusqu'à N secondes. Sans lui, collect se termine avec le code 3 si le run est encore en cours.

Autres commandes :

node "$DELEGATE" status <run_id>                 # starting|running|stalled|adrift|lost|done
node "$DELEGATE" collect <run_id> --json         # le résultat lisible par machine — analysez-le
node "$DELEGATE" list                            # tous les runs, du plus ancien au plus récent
node "$DELEGATE" prune --keep 20 --yes           # supprime les anciens artefacts de run
node "$DELEGATE" contract                        # drapeaux, champs, codes de sortie lisibles par machine

Lecture du résultat

Statut       SUCCESSFUL
Parce que    harness_telemetry

Modifications
  mesurées   greeting.txt
  déclarées  greeting.txt

Permission   demandée=bypass  appliquée=codex: --dangerously-bypass-approvals-and-sandbox

Trois champs portent l'essentiel du sens :

  • status — successful / failed / abandoned.
  • status_provenance.primary — pourquoi ce statut, en un mot : timeout, spawn_error, signal, exit_code, parse_error, telemetry_incomplete, harness_telemetry, self_report, head_moved, index_moved, relay_aborted, supervisor_lost, legacy. Ne rapportez jamais un statut sans savoir lequel de ceux-ci l'a produit. evidence liste toutes les observations qui étaient vraies, pas seulement celle qui a gagné.
  • dirty_paths_changed — ce que git a mesuré, par opposition à files_claimed, qui est ce que le délégué a dit. files_mismatch signale un désaccord.

Permissions

Par défaut, contournement total. Le délégué exécute des commandes arbitraires sans supervision.

--sandbox demande le mode lecture seule réel de chaque CLI (tableau ci-dessus) et active le fil coup-de-poing : read_only_violation est true / false / null. null signifie inconnu — git était indisponible ou la couverture d'empreinte était incomplète. Il n'est jamais réduit à false.

false ne signifie pas "aucune écriture n'a eu lieu". Cela signifie qu'aucun delta d'état final couvert n'a été détecté. Il ne peut pas voir une écriture puis annulation, quoi que ce soit dans .gitignore, ni aucune écriture en dehors du dépôt. true ne signifie pas que le délégué l'a fait — une modification concurrente dans la même arborescence de travail semble identique.

L'enveloppe demande au délégué de ne pas commiter, mais c'est une politique, pas une application. Ce qui l'applique, c'est la mesure : si HEAD bouge pendant la fenêtre du run, le résultat est forcé en révision requise (head_moved) sauf si vous avez passé --allow-commit.

Continuer un run

node "$DELEGATE" start --harness codex --cwd <même répertoire> --resume <run_id> \
  --task "La correction est bonne, mais utilise le vrai fixture au lieu d'un mock."

N'envoyez que le delta. Resume obtient un nouveau run_id avec parent_run_id défini, et refuse si le harnais, le répertoire de travail ou l'identifiant de session du parent ne correspondent pas.

Un envoi repris répète chaque règle de politique plutôt que de supposer que la session parente les honore toujours.

Drapeaux

drapeauusage
--cwd DIRrépertoire de travail — toujours le définir explicitement
--model Mremplacer le modèle
--timeout SECpar défaut 1800 ; validé en amont ; à l'expiration, l'arborescence est tuée → abandoned
--deliverable TEXTce qui doit être remis ("un diff unifié, ne pas commiter")
--constraint TEXTrègle supplémentaire répétable
--sandboxdemander le mode lecture seule du harnais
--allow-commitautoriser le commit, et cesser de traiter un HEAD déplacé comme révision requise
--resume <run_id>continuer la session d'un run terminé avec une tâche delta
--clean-env / --keep-env Nne donner à la CLI que les bases d'exécution ; répéter --keep-env par variable nécessaire à l'authentification
--rawenvoyer la tâche textuellement (perd le statut/résumé ; incompatible avec --resume)

Pièges

  1. Le code de sortie 0 ne signifie pas que la tâche est terminée — et jusqu'à ce refactoring, un code de sortie non nul ne signifiait pas un échec. Les adaptateurs recevaient le code de sortie et aucun ne le lisait, donc un événement en forme de succès plus un code de sortie 1 était publié comme successful. Corrigé ; verrouillé par le cas REPAIR-D1 de test/run.mjs. Lisez toujours status_provenance, jamais exit_code seul.
  2. Les champs de tokens ont des significations différentes selon le harnais. Les input_tokens / cache_creation / cache_read de Claude sont disjoints — additionnez-les (une sonde a rapporté input_tokens : 2 pour une requête qui en envoyait vraiment 58 065). Les input_tokens de Codex sont inclusifs de cached_input_tokens — soustrayez pour le compte frais. Utilisez input_total / input_fresh ; usage_raw conserve les chiffres propres du harnais pour audit mais n'est jamais affiché comme total.
  3. Les totaux ne sont pas comparables entre harnais. OpenCode émet un step_finish par étape et le pilote les additionne, donc le contexte renvoyé à chaque étape est compté à chaque fois. Même tâche triviale : 66 341 (codex), 117 014 (claude), 426 523 (opencode). Pas un classement d'efficacité.
  4. Déléguer à claude a un plancher d'environ 58k tokens. claude -p charge CLAUDE.md et chaque compétence découverte avant de lire la tâche.
  5. Codex hérite de vos serveurs MCP. Si codex semble lent, lisez runs/<run_id>/stderr.log — le délai vient généralement du MCP, pas du modèle.
  6. Codex émet des événements item.type: "error" lors de runs réussis. Seuls turn.failed ou un turn.completed manquant comptent.
  7. Le contournement total est vraiment non isolé. Un délégué OpenCode a un jour écrit un fichier à l'extérieur de son --cwd. Utilisez --sandbox, ou un répertoire jetable.
  8. Tous les harnais ne rapportent pas tous les champs. Copilot n'émet aucun nombre de tokens (fidelity : "unavailable" — des zéros signifient inconnu, pas gratuit). Codex n'émet ni coût ni modèle nulle part dans son JSONL, donc cost_usd et model sont null par nature, pas par une erreur d'analyse — cost_reported / model_reported disent lesquels, et le résultat imprimé indique "non rapporté par ce harnais". Claude rapporte les deux ; OpenCode rapporte le coût.
  9. Le texte de la tâche n'atteint jamais un shell. Chaque CLI est résolue en un exécutable réel et lancée avec shell:false.
  10. pi persiste une session dans son propre espace de stockage. --no-session n'est volontairement pas passé — sans session, il n'y a rien à reprendre. Les sessions atterrissent dans ~/.pi/agent/sessions/<slug-cwd>/, indexées par répertoire de travail ; prune n'y touche pas. L'authentification de Pi est basée sur fichier (~/.pi/agent/auth.json), donc --clean-env ne la casse pas.
  11. Un run dont le superviseur est tué est lost, pas bloqué. collect synthétise un résultat terminal à partir du journal et des logs. Son delta git est null : aucune base de début de run n'a survécu, et rapporter false serait une assurance qu'aucune mesure n'a été faite.
  12. Les identifiants de run sont validés. Ils doivent correspondre à <harnais>-<14 chiffres>-<6 hex>, et doivent se résoudre directement sous le répertoire des runs. Un identifiant fourni par l'appelant ne peut pas en sortir par traversée.
  13. Un superviseur mort dont le harnais est encore vivant est adrift, pas lost. collect refuse de publier, car un résultat écrit à ce moment instantané serait un run encore en mouvement. Attendez l'enfant, ou tuez le pid que status nomme. prune ne supprimera pas non plus un run adrift.
  14. DELEGATE_BIN_<HARNASS> remplace l'emplacement où un binaire est trouvé — par exemple DELEGATE_BIN_CODEX=/opt/codex/bin/codex. C'est aussi ainsi que la suite de tests pilote un faux harnais de bout en bout sans dépenser un token.

Dépannage

symptômecause / correctif
<bin> introuvable dans PATHcette CLI n'est pas installée ; exécutez doctor
trouvé <chemin> mais impossible de résoudre ce qu'il lancela CLI est installée derrière un shim .cmd non-npm que ce pilote ne peut pas décoder
doctor affiche BROKEN: probe timed outgénéralement un démarrage à froid ; réexécutez doctor avant de conclure quoi que ce soit
le superviseur n'a pas démarré (code 5)le superviseur détaché n'a jamais accusé réception ; vérifiez runs/<id>/journal.jsonl. Le run est finalisé failed avec containment_evidence: "le harnais n'a jamais été lancé" ; si le journal ne contient que created et terminal et que le pid du superviseur est parti, aucun agent n'a tourné
run <id> encore en cours d'exécution (code 3)ajoutez --wait <secondes>
Refus de publier … toujours en cours (code 6)le run est adrift : le superviseur est mort mais le harnais vit. Attendez, ou tuez le pid qu'il nomme
un autre processus finalise ce run (code 7)un écrivain actif détient la revendication ; réessayez dans un instant
écrit par un pilote différent (code 8)le résultat porte un schéma inconnu ; cette version ne devinera pas
statut abandoned, provenance supervisor_lostle superviseur a été tué ; inspectez l'arborescence de travail avant de redéléguer
statut failed, provenance head_moved / index_movedquelque chose a commité ou stagé pendant le run ; l'arborescence est préservée, examinez-la
Résumé indique (aucun résumé produit)le délégué n'a jamais émis le bloc de résultat ; lisez runs/<run_id>/stdout.log

Fichiers

Les artefacts de run se trouvent dans $DELEGATE_RUNS_DIR/<run_id>/ (prompt.txt, meta.json, journal.jsonl, stdout.log, stderr.log, result.json). Non défini, DELEGATE_RUNS_DIR par défaut est runs/ à côté du pilote — ce qui est le répertoire partagé du plugin lors d'une installation via plugin, donc définissez-le. Limitez la taille des logs avec DELEGATE_MAX_LOG_BYTES (par défaut 32 Mo par flux) et la fenêtre de rétention après limite avec DELEGATE_LOG_TAIL_BYTES (par défaut 512 Ko).

Passé la limite, le pilote conserve des enregistrements analysés complets plutôt qu'un suffixe d'octets, donc la télémétrie reste analysable. Les enregistrements que la fenêtre ne peut pas contenir sont comptés dans records_dropped — une valeur non nulle signifie que le statut est toujours fiable mais que la réponse finale du délégué peut être incomplète.

⚠️ Les artefacts contiennent le texte de votre tâche, l'invite complète et la sortie brute du harnais — traitez-les comme sensibles. La finalisation masque les formes de tokens et les paires NOM=valeur ressemblant à des identifiants dans stdout.log et stderr.log (pas dans result.json). Sur POSIX, le répertoire des runs est chmod 0700 ; sur Windows, les permissions sont héritées et ce pilote ne peut pas les restreindre. Un collect réussi supprime les runs terminés plus vieux que DELEGATE_PRUNE_DAYS jours (par défaut 30 ; 0 désactive) ; nettoyez plus tôt avec prune.

Aller plus loin

  • Pour un lot de vérifications CLI locales connues, lisez le contrat natif du runner de vérifications. Il couvre les plans d'argv JSON, les tentatives immuables, la collecte bornée et l'invocation PowerShell. Utilisez la même référence pour collect --summary, les diagnostics uniquement par battement de cœur et les délais de démarrage optionnels.

  • contracts/status-precedence.md — comment un statut est décidé, et le produit croisé à tester

  • contracts/git-fields.md — ce que le fil coup-de-poing mesure et ce qu'il ne peut pas voir

  • contracts/result-schema-v2.md — la forme du résultat, lecture arrière v1, journal, mono-écrivain

  • references/writing-the-brief.md — comment rédiger une tâche que le délégué peut exécuter à l'aveugle

  • references/reviewing-the-result.md — comment examiner ce qui revient, y compris le balayage

  • references/task-queues.md — exécuter plusieurs tâches dépendantes sans perdre le fil

Tests : node test/run.mjs, depuis le répertoire de cette compétence. Régressions d'exécution : node --test test/execution.test.mjs (fixtures CLI Node/Python).

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

samykabu/github-wiki-publish

Publish or update pages, reports, diagrams and assets in a GitHub repository Wiki, preserving existing content and verifying the published result. Use for GitHub Wiki publishing or sync requests, rather than GitHub Pages deployment or general documentation generation.

samykabu/illustrate

Draws diagrams, charts, and technical illustrations (44 types) as self-contained HTML with inline SVG, plus optional SVG/PNG/PDF export, in the project's tracked color and font theme. Use this skill whenever the user asks to draw, diagram, visualize, chart, map, sketch, or illustrate something, even without saying 'illustrate': architecture or system design, infrastructure, cloud or deployment topology, data flow, flowcharts, sequence, state machines, ER or database schema, UML class, dependency graphs, org charts, timelines, Gantt, swimlanes, process or workflow maps, user journeys, kanban, story maps, quadrants, Venn, pyramids, fishbone root-cause, Sankey, Wardley maps, bar, line, scatter, heatmap, waterfall, treemap, radar, or polar charts, and exploded or axonometric views. Also use to redraw .drawio, Mermaid (.mmd), or .excalidraw files, add a diagram to docs, a PR, or a spec, set up the illustration theme, or export a diagram. Not for photos or AI-generated raster images.

samykabu/progress-report

Keep a live, deterministic progress report for a Markdown plan checklist or a Spec Kit feature. Collects task state from the plan file, hook events from Claude Code or Codex, and lane, blocker and decision facts you record, then renders a browser view and a Markdown export with no agent spent on upkeep.

samykabu/user-manual

Create, update, audit and publish a standalone application User Manual with End User, Administrator and Technical editions, in English and optional Arabic. Use without Spec Kit to start a manual, document a feature or module, audit coverage, write API documentation (OpenAPI, AsyncAPI, GraphQL, webhooks), release notes and migration guides, plan and capture UI screenshots, set up private previews and versioned release…

Skills associés