claude-code-task

TotalClaw 作者 totalclaw

在后台异步启动 Claude Code,并自动传送到 Telegram/WhatsApp。用于编码、重构、代码库研究、文件生成和复杂的多步骤自动化。不适用于快速的一次性问题或实时交互式任务。包括严格的线程安全路由+E2E操作员验证工作流程。

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install totalclaw:totalclaw~vsevolodustinov-claude-code-task
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Atotalclaw~vsevolodustinov-claude-code-task/file -o vsevolodustinov-claude-code-task.md
## 概述(中文)

在后台异步启动 Claude Code,并自动传送到 Telegram/WhatsApp。用于编码、重构、代码库研究、文件生成和复杂的多步骤自动化。不适用于快速的一次性问题或实时交互式任务。包括严格的线程安全路由+E2E操作员验证工作流程。

## 原文

# Claude Code Task (Async)

Run Claude Code in background — zero OpenClaw tokens while it works. Results delivered to WhatsApp or Telegram automatically.

## Important: Claude Code = General AI Agent

Claude Code is NOT just a coding tool. It's a full-powered AI agent with web search, file access, and deep reasoning. Use it for ANY complex task:

- **Research** — web search, synthesis, competitive analysis, user experience reports
- **Coding** — create tools, scripts, APIs, refactor codebases
- **Analysis** — read and analyze files, data, logs, source code
- **Content** — write docs, presentations, reports, summaries
- **Automations** — complex multi-step workflows with file system access

Give it prompts the same way you'd talk to a smart human — natural language, focused on WHAT you need, not HOW to do it.

**NOT for:**
- Quick questions (just answer directly)
- Tasks needing real-time interaction

## Quick Start

## What "run tests" means for this skill (critical)

When user asks things like:
- "прогони все тесты"
- "run tests"
- "проверь что всё работает"

it means **run the full E2E operator validation flow** for `run-task.py` routing + notifications.

It does **NOT** mean `pytest`/`unittest` discovery by default.

Required behavior:
1. Run routing validation first (`--validate-only`).
2. Launch smoke/E2E scenario via `nohup` and file-based prompt.
3. Wait for completion through normal async flow (wake/event), not same-turn blocking.
4. Report PASS/FAIL against E2E criteria (routing, heartbeat, mid-task update, completion delivery).

Use the canonical protocol: **[references/testing-protocol.md](references/testing-protocol.md)** and the section below **Full E2E Test (reference)**.

## Async Boundary Rule (mandatory)

`run-task.py` is asynchronous orchestration.

After a successful `nohup` launch, the correct behavior is:
1. Send a short launch acknowledgment (PID/log/session), then
2. **Stop this turn immediately**.
3. Continue only when wake/completion event arrives in the same session.

Do **not** keep waiting in the same turn for Claude Code completion.
Do **not** poll and then summarize in the same turn unless user explicitly asked for active live monitoring.

Anti-pattern:
- ❌ Launch `run-task.py` and keep responding as if completion should appear in this turn.

Correct pattern:
- ✅ Launch `run-task.py` → acknowledge launch → stop → wait for wake.

## Launch Confirmation Gate (mandatory)

Never claim "launched" until you have **positive launch proof**.

Required proof checklist (all):
1. `nohup` command returned a PID,
2. process is alive (`ps -p <PID>`),
3. run log contains `🔧 Starting Claude Code...` (or equivalent startup marker),
4. routing was validated (`--validate-only`) for Telegram thread runs.

If launch fails with `❌ Invalid routing`:
- resolve via `sessions_list`,
- rerun with explicit `--notify-channel telegram --notify-thread-id <id> --notify-session-id <uuid>`,
- re-check proof checklist,
- only then send launch acknowledgment.

Do not send "Claude Code ушёл в работу" before this gate is satisfied.

## Pre-launch planning note (mandatory)

Before launching Claude Code, post a short plan in chat:
- how you plan to solve the task,
- what result you expect from this run,
- any clarifying questions/assumptions,
- whether you expect one iteration or a staged multi-iteration approach.

If staged: explicitly say this run is "phase 1" and what signal will decide phase 2.

## Telegram Thread Safety (must-follow)

For Telegram thread runs, `run-task.py` is designed to either route correctly or fail immediately.

### Mandatory step before launch
Resolve the **current runtime session key** first (source of truth), then launch with it.

- Get current key via `sessions_list` (or existing runtime context)
- If key is `agent:main:main:thread:<THREAD_ID>` → use it directly in `--session`
- Never derive `--session` from `chat_id`/sender id heuristics

### Rules
- Use only `--session "agent:main:main:thread:<THREAD_ID>"` for thread tasks
- Never use `agent:main:telegram:user:<id>` for thread tasks
- If routing metadata is inconsistent (thread/session UUID/target mismatch), script exits with `❌ Invalid routing`
- Default mode is `--telegram-routing-mode auto`:
  - allows non-thread Telegram for setups without thread sessions
  - blocks ambiguous user-scope session key (`agent:main:telegram:user:<id>`) unless explicitly forced
  - blocks non-thread launch if a recent thread session exists for same target (likely misroute)
- Force strict thread-only behavior with `--telegram-routing-mode thread-only`
- Force non-thread behavior with `--telegram-routing-mode allow-non-thread` or `--allow-main-telegram`

This is intentional: **abort fast > silent misroute**.

⚠️ **ALWAYS launch via nohup** — exec timeout (2 min) will kill the process!

⚠️ **NEVER put the task text directly in the shell command** — quotes, special characters, and newlines WILL break argument parsing. Always save the prompt to a file first, then use `$(cat file)`.

### WhatsApp

```bash
# Step 1: Save prompt to a temp file
write /tmp/cc-prompt.txt with your task text

# Step 2: Launch with $(cat ...)
nohup python3 {baseDir}/run-task.py \
  --task "$(cat /tmp/cc-prompt.txt)" \
  --project ~/projects/my-project \
  --session "agent:main:whatsapp:group:<JID>" \
  --timeout 900 \
  > /tmp/cc-run.log 2>&1 &
```

The `--session` key (e.g. `agent:main:whatsapp:group:120363425246977860@g.us`) is used to auto-detect the WhatsApp target.

### Telegram (thread-safe default)

```bash
# ALWAYS use the current thread session key from context:
# agent:main:main:thread:<THREAD_ID>
nohup python3 {baseDir}/run-task.py \
  --task "$(cat /tmp/cc-prompt.txt)" \
  --project ~/projects/my-project \
  --session "agent:main:main:thread:<THREAD_ID>" \
  --timeout 900 \
  > /tmp/cc-run.log 2>&1 &
```

> Do **NOT** use `agent:main:telegram:user:<id>` for thread tests/runs.
> That routes to main chat scope and can drift from the source thread.

### Telegram Threaded Mode (1:1 DM with threads)

When Marvin is used in Telegram Threaded Mode, each thread has its own session key like `agent:main:main:thread:369520`.

**Fail-safe routing (NEW):** `run-task.py` now enforces strict thread routing.
- If `--session` contains `:thread:<id>`, the script **refuses to start** unless Telegram target + thread session UUID are resolved.
- It auto-resolves missing values from `sessions_list` when possible.
- If the session is inactive and not returned by API, it falls back to local session files: `~/.openclaw/agents/main/sessions/*-topic-<thread_id>.jsonl`.
- If provided `--notify-session-id` mismatches the session key, it exits with error.
- Result: misrouted launches/heartbeats to main chat are blocked before Claude starts.

Use `--notify-session-id` to wake the exact thread session:

```bash
nohup python3 {baseDir}/run-task.py \
  --task "$(cat /tmp/cc-prompt.txt)" \
  --project ~/projects/my-project \
  --session "agent:main:main:thread:369520" \
  --timeout 900 \
  > /tmp/cc-run.log 2>&1 &
```

All 5 notification types route to the DM thread when `--session` key contains `:thread:<id>` ✅

- `--notify-session-id` — optional override. Usually auto-resolved from session metadata/files.
- `--notify-thread-id` — optional override. Usually auto-extracted from `--session`.
- `--reply-to-message-id` — optional debug field; avoid for DM thread routing.
- `--validate-only` — resolve routing and exit (no Claude run). Use this to verify thread launch args safely.

- `--notify-channel` — optional channel hint (`telegram`/`whatsapp`); target is always auto-resolved from session metadata
- `--timeout` — max runtime in seconds (default: 7200 = 2 hours)
- `--completion-mode` — optional legacy hint (`single` default, `iterate` if explicitly needed)
- `--max-iterations` — optional budget hint when using