task-poke
Bir Claude Code Mod'u. Bir ana döngü turu bittiğinde ve task listesi hâlâ pending ya da in-progress task taşıyorsa bir devam prompt'u gönderir. Engine'in kendi task listesini session'ın başlangıcında okur, yani bugün resume ettiğiniz bir session'da haftalar önce açılmış bir liste ilk turdan sayılır, o task'lar oluşturulurken mod kurulu olsun ya da olmasın. Arka arkaya 99 poke'tan sonra, /task-poke limit <n> ile ayarladığınız limitten sonra ya da hiçbir şeyi ilerletmeyen üç poke'tan sonra durur. Yazdığınız bir prompt sayımı sıfırlar.
İki task formatını da okur:
TodoWrite: her çağrı bütün listenin yerini alır.TaskCreate,TaskUpdateveTaskList(Claude Code 2.1.142'den beri varsayılan):TaskCreatebir task ekler ve id tool sonucundan gelir ({ task: { id } }).TaskUpdatebir task'ıtaskIdile patch'ler (hamidvetask_idkey'leri de okunur).status: "deleted"bir task'ı kaldırır. BirTaskListsonucu bütün listeyi taşır, yani replay'in tuttuğunun yerini alır ve ondan sonraki satırlar üstüne uygulanır.
Sonraki bir TodoWrite, Task tool'larından kurulmuş her state'in yerini alır.
Sayım ve transcript penceresi
$.session.messages() uzun bir transcript'in yalnız en yeni mesajlarını cevaplar, yani o pencerenin replay'i ondan önce oluşturulmuş hiçbir task'ı görmez. Mod bu boşluğu iki taraftan kapatır:
- Session'ın başlangıcında engine'in kendi listesini bir kere okur,
$.tool.call({ tool: 'TaskList' })ile. Resume edilmiş bir session,TaskCreateçağrısı pencerenin çok dışında kalan task'ları geri getirir ve bu okuma onları ilk turdan sayar. Çağrı konuşmaya hiçbir mesaj taşımaz: bir tool satırı bırakmaz ve model onu hiç görmez (ölçüldü). Başarısız olduğunda, task tool'ları kapalı olduğu için ya da engine reddettiği için, kırmızı bir satır bunu söyler ve transcript tek başına cevaplar. - Sonraki her pencere, son okumanın listesi üzerine replay edilir, yani 8000 mesaj önce oluşturulmuş ve o günden beri dokunulmamış bir task sayılı kalır.
Modelin kendisinin çağırdığı bir TaskList aynı okunur: sonucu bütün listedir ve replay'in tuttuğunun yerini alır.
Her modelde task tool'ları
Claude Code task takip tool'larını yalnız Claude 3.x, Opus 4.0 ile 4.7, Sonnet 4.0 ile 4.6 ve Haiku 4.5 üzerinde sunar. Diğer her modelde mod'un sayacak bir şeyi olmaz. Bu yüzden mod session.start anında Claude Code process'i için CLAUDE_CODE_ENABLE_TODO_TOOLS=1 ayarlar ve Claude Code task tool'larını her modelde sunar.
- Mod kendiniz ayarladığınız bir değeri değiştirmez.
CLAUDE_CODE_ENABLE_TODO_TOOLS=0task tool'larını kapalı tutar. - Mod,
/task-poke offsaklıyken değişkeni ayarlamaz./task-poke offtask tool'ları üzerinde sonraki session'dan itibaren geçerli olur. - Değişken ayrıca session'ın başlattığı her Bash komutuna ve MCP server'a ulaşır.
CLAUDE_CODE_ENABLE_TASKS=falseTask tool'larınıTodoWriteile değiştirir. Mod iki formatı da okur.
Ne gösterir
sidebar açıkken sayım orada session boyunca duran bir task list section'ı olarak durur, her turda yeniden yazılır:
task-poke: task list
3 unfinished tasks, poke 2/99
Satır son poke'un altında yeşil, onda sarı ve poke'lar durduktan sonra kırmızıdır. Bitmemiş hiçbir şey kalmadığında section iner. Bulgular bunun yerine stream'e gider, kırmızı olarak, böylece sonraki sayım onları pane'den almaz: poke limitinde duruş, hiçbir şeyi ilerletmeyen üç poke sonrası duruş, engine'in düşürdüğü bir poke ve mod'un okuyamadığı bir task listesi.
Sidebar kapalıyken ya da o mod kurulu değilken yalnız poke gönderen bir tur satırını transcript'e yazar ve üç bulgu eskiden olduğu gibi transcript satırıdır.
Bir poke hiçbir şeyi ilerletmediğinde
Bir poke bir tur satın alır. O tur hiçbir task'ın status'unu değiştirmediyse ve hiçbir tool çalıştırmadıysa poke hiçbir şeyi ilerletmemiştir: model kelimelerle cevap vermiştir ve sonraki poke aynı cevabı yeniden satın alır. Arka arkaya üç böyle poke'tan sonra mod durur ve kırmızı bir entry bunu söyler:
task-poke: stopped after 3 pokes that moved nothing: no task changed status and no tool ran. Send a prompt to start again.
Sayım, bir şeyi ilerleten ilk turda sıfıra döner, yani uzun bir task üzerinde çalışan bir model bunun yüzünden hiç durdurulmaz. Sonraki prompt'unuz poke'ları yeniden başlatır.
Ne zaman poke göndermez
- Tur kesildi, reddedildi ya da bir API hatasıyla bitti (
reasonanswerdeğil). - Tur bir subagent'ta çalıştı.
- Son assistant mesajı
AskUserQuestionçağırdı. - Son prompt'unuzdan beri poke limiti gönderildi. Kırmızı bir entry duruşu bildirir.
- Arka arkaya üç poke hiçbir şeyi ilerletmedi, yukarıdaki gibi.
/task-poke offayarlı.
Komutlar
/task-poke durum
/task-poke on açar (varsayılan), session'lar arasında saklanır
/task-poke off kapatır, session'lar arasında saklanır
/task-poke limit 20 arka arkaya en fazla 20 poke; 1 ile 999 arası, varsayılan 99, session'lar arasında saklanır
Kurulum
claude plugin marketplace add KilimcininKorOglu/claude-code-mods
claude plugin install task-poke@kilimcininkoroglu-mods
Function hook'lar early access. Flag olmadan hiçbir şey yüklenmez:
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude
Tek bir session için yerel bir checkout'tan yükleyin:
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude --plugin-dir plugins/task-poke
Flag'i kalıcı yapmak için ~/.claude/settings.json dosyasına ekleyin (2.1.278 üzerinde ölçüldü):
{ "env": { "CLAUDE_CODE_ENABLE_FUNCTION_HOOKS": "1" } }
Kurulumdan sonra
Claude Code'u yeniden başlatın. Mod task tool'larını session başlangıcında açar, yani yukarıdaki listenin dışındaki bir modelde task tool'ları sonraki session'dan gelir.
Nereye uzanır
Claude Code 2.1.278 üzerinde claude plugin validate ile doğrulandı:
❯ ./register.ts hooks: session.start, command.run{command=task-poke}, prompt.submit, turn.complete
❯ ./register.ts calls: $.command.register, $.env.get, $.env.set, $.prompt.submit (via sendPoke), $.session.messages (via afterTurn), $.sidebar.clear (via clearCount), $.sidebar.set (via toCount, toStream), $.store.get, $.store.set, $.tool.call (via seedTasks), $.ui.log (via toCount, toStream)
❯ ./register.ts env writes: CLAUDE_CODE_ENABLE_TODO_TOOLS
❯ ./register.ts env reads: CLAUDE_CODE_ENABLE_TODO_TOOLS
Reach L2, Claude'u sürer. Transcript'i okur. Bir environment variable yazar.
1. Okur: transcript'i $.session.messages üzerinden (TodoWrite, TaskCreate, TaskUpdate, TaskList ve AskUserQuestion tool adları, input'ları ve sonuçları); engine'in task listesini session başlangıcında tek bir $.tool.call ile; her prompt'un origin kind'ını, hiçbir zaman metnini değil; CLAUDE_CODE_ENABLE_TODO_TOOLS
2. Çalıştırır: session başlangıcında ve /task-poke on anında salt okuma bir TaskList çağrısı; bitmemiş task'larla biten her ana döngü turu için bir $.prompt.submit, arka arkaya en fazla 99 ya da ayarladığınız limit kadar, ve hiçbir şeyi ilerletmeyen arka arkaya en fazla 3 tane; ayarlı değilken session başına bir kere CLAUDE_CODE_ENABLE_TODO_TOOLS=1 ayarlar
3. Gönderir: yalnız sabit poke prompt'unu, normal bir tur olarak
4. Saklar: $.store içinde bir boolean (enabled) ve poke limitini; environment variable yalnız process boyunca yaşar
5. Düşman girdi: transcript'ten hiçbir metin poke prompt'una ulaşmaz; bilinmeyen bir task status'u, task.id taşımayan bir TaskCreate sonucu ya da id taşımayan bir TaskList satırı poke'ları durdurur ve hata değişene kadar bir satır hatayı adlandırır
Sınırlar
$.session.messages()en yeni 4096 mesajı döndürür. Session başlangıcındaki okuma ve mod'un turlar arasında tuttuğu liste, o pencerenin kaybettiğini kapsar.- Bir
TaskGetsonucu parse edilmez. State'iTodoWrite,TaskCreate,TaskUpdateveTaskListkurar. - Mod'un tuttuğu liste session'ın plugin state'inde yaşar. Bir
/reload-pluginssession.startolayını yeniden çalıştırır, yani engine'in listesi de onunla yeniden okunur. - Yeni bir session boş bir engine listesiyle başlar: Claude Code task'ları resume edilmiş bir session'a taşır, yeni bir session'a değil (ölçüldü).
Geliştirme
make install # eslint, typescript-eslint, typescript
make lint # complexity limiti 10, üstünde build'i düşürür
make typecheck # /plugin-types ile üretilen .claude/types/ gerekir
make validate
make test # claude plugin test
task-poke
A Claude Code Mod. When a main-loop turn ends and the task list still has pending or in-progress tasks, it submits a continue prompt. It reads the engine's own task list at the session's start, so a list opened weeks ago in a session you resume today is counted from the first turn, whether or not the mod was installed when those tasks were made. It stops after 99 consecutive pokes, after the limit you set with /task-poke limit <n>, or after three pokes in a row that moved nothing. A prompt you type resets the count.
It reads both task formats:
TodoWrite: each call replaces the whole list.TaskCreate,TaskUpdateandTaskList(default since Claude Code 2.1.142):TaskCreateadds a task, and the id comes from its tool result ({ task: { id } }).TaskUpdatepatches a task bytaskId(the rawidandtask_idkeys are also read).status: "deleted"removes a task. ATaskListresult carries the whole list, so it replaces what the replay held, and the rows after it apply on top.
A later TodoWrite replaces any state built from the Task tools.
The count and the transcript window
$.session.messages() answers the newest messages of a long transcript alone, so a replay of that window sees no task created before it. The mod closes that gap from two sides:
- At the session's start it reads the engine's own list once, with
$.tool.call({ tool: 'TaskList' }). A resumed session brings back tasks whoseTaskCreatesits far outside the window, and this reading counts them from the first turn. The call carries no message into the conversation: it leaves no tool row and the model never sees it (measured). When it fails, because the task tools are off or the engine refused it, one red line says so and the transcript answers alone. - Each later window is replayed over the list of the last reading, so a task created 8000 messages ago and never touched since stays counted.
A TaskList the model itself calls is read the same way: its result is the whole list, and it replaces what the replay held.
Task tools on every model
Claude Code offers the task-tracking tools only on Claude 3.x, Opus 4.0 to 4.7, Sonnet 4.0 to 4.6 and Haiku 4.5. On every other model the mod has nothing to count. So at session.start the mod sets CLAUDE_CODE_ENABLE_TODO_TOOLS=1 for the Claude Code process, and Claude Code then offers the task tools on every model.
- The mod does not change a value you set yourself.
CLAUDE_CODE_ENABLE_TODO_TOOLS=0keeps the task tools off. - The mod does not set the variable while
/task-poke offis stored./task-poke offtakes effect on the task tools from the next session. - The variable also reaches every Bash command and MCP server the session starts.
CLAUDE_CODE_ENABLE_TASKS=falsereplaces the Task tools withTodoWrite. The mod reads both formats.
What it shows
While the sidebar is open, the count stands there as a task list section for the session, rewritten at each turn:
task-poke: task list
3 unfinished tasks, poke 2/99
The line is green below the last poke, yellow at it, and red once the pokes stopped. The section goes down when nothing is unfinished. Findings go into the stream instead, in red, so the next count does not take them off the pane: the stop at the limit of pokes, the stop after three pokes that moved nothing, a poke the engine dropped, and a task list the mod cannot read.
With the sidebar closed, or without that mod installed, only a turn that sent a poke writes its line to the transcript, and the three findings are transcript lines, as before.
When a poke moves nothing
A poke buys a turn. When that turn changed no task's status and ran no tool, the poke moved nothing: the model answered with words and the next poke buys the same answer again. After three such pokes in a row the mod stops and one red entry says so:
task-poke: stopped after 3 pokes that moved nothing: no task changed status and no tool ran. Send a prompt to start again.
The count goes back to zero at the first turn that moved something, so a model working through a long task is never stopped by this. Your next prompt starts the pokes again.
When it does not poke
- The turn was interrupted, refused, or ended on an API error (
reasonis notanswer). - The turn ran in a subagent.
- The last assistant message called
AskUserQuestion. - The limit of pokes was sent since your last prompt. One red entry reports the stop.
- Three pokes in a row moved nothing, as above.
/task-poke offis set.
Commands
/task-poke status
/task-poke on enable (default), stored across sessions
/task-poke off disable, stored across sessions
/task-poke limit 20 at most 20 pokes in a row; 1 to 999, 99 by default, stored across sessions
Install
claude plugin marketplace add KilimcininKorOglu/claude-code-mods
claude plugin install task-poke@kilimcininkoroglu-mods
Function hooks are early access. Nothing loads without the flag:
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude
Load it from a local checkout for one session:
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude --plugin-dir plugins/task-poke
To keep the flag on, add this to ~/.claude/settings.json (measured on 2.1.278):
{ "env": { "CLAUDE_CODE_ENABLE_FUNCTION_HOOKS": "1" } }
After installing
Restart Claude Code. The mod turns the task tools on at session start, so on a model outside the list above the task tools come from the next session.
What it can reach
Validated with claude plugin validate on Claude Code 2.1.278:
❯ ./register.ts hooks: session.start, command.run{command=task-poke}, prompt.submit, turn.complete
❯ ./register.ts calls: $.command.register, $.env.get, $.env.set, $.prompt.submit (via sendPoke), $.session.messages (via afterTurn), $.sidebar.clear (via clearCount), $.sidebar.set (via toCount, toStream), $.store.get, $.store.set, $.tool.call (via seedTasks), $.ui.log (via toCount, toStream)
❯ ./register.ts env writes: CLAUDE_CODE_ENABLE_TODO_TOOLS
❯ ./register.ts env reads: CLAUDE_CODE_ENABLE_TODO_TOOLS
Reach L2, drives Claude. Reads the transcript. Writes one environment variable.
1. Reads: the transcript through $.session.messages (tool names, inputs and results of TodoWrite, TaskCreate, TaskUpdate, TaskList and AskUserQuestion); the engine's task list through one $.tool.call at the session's start; the origin kind of each prompt, never its text; CLAUDE_CODE_ENABLE_TODO_TOOLS
2. Runs: one read-only TaskList call at the session's start and at /task-poke on; one $.prompt.submit per main-loop turn that ends with unfinished tasks, at most 99 in a row, or the limit you set, and at most 3 in a row that move nothing; sets CLAUDE_CODE_ENABLE_TODO_TOOLS=1 once per session when it is unset
3. Sends: only the fixed poke prompt, as a normal turn
4. Persists: one boolean (enabled) and the poke limit in $.store; the environment variable lasts for the process only
5. Hostile input: no text from the transcript reaches the poke prompt; an unknown task status, a TaskCreate result without task.id or a TaskList row without an id stops the pokes, and one line names the error until the error changes
Limits
$.session.messages()returns the newest 4096 messages. The reading at the session's start and the list the mod keeps between turns cover what that window loses.- A
TaskGetresult is not parsed.TodoWrite,TaskCreate,TaskUpdateandTaskListbuild the state. - The list the mod keeps lives in the session's plugin state. A
/reload-pluginsrunssession.startagain, so the engine's list is read again with it. - A new session starts with an empty engine list: Claude Code carries tasks into a resumed session, not into a fresh one (measured).
Development
make install # eslint, typescript-eslint, typescript
make lint # complexity limit 10, fails the build above it
make typecheck # needs .claude/types/ from /plugin-types
make validate
make test # claude plugin test