A long-task terminal operations manual for POSIX shell, macOS, and Linux. It does not falsely claim native Windows compatibility; Windows users should use it in WSL or another POSIX environment.
Customer-readable explanation
What this skill can do
| Customer wants | Skill will do | Customer can see |
|---|---|---|
| Start or observe a long task | Start a tmux/background task with parameterized session, log directory, and command | command, workdir, session/PID, log path, and current status |
| Determine whether the task is stalled | Cross-check logs, CPU, and network/subprocess progress within the user-specified observation window | Evidence for each signal and a conclusion of "running/suspected stalled/unable to determine" |
| Recover or terminate the task | First confirm the target and data risk, then proceed in the order TERM→recheck→KILL | Each signal, confirmation point, exit status, and follow-up recovery recommendation |
How customers use it
Provide the following inputs; if inputs that would change the termination target or log destination are missing, ask first and do not guess:
- The command to run or diagnose, and the working directory;
- An existing PID or tmux session (if applicable);
session_name、log_dir、stall_window_seconds、term_grace_seconds;- Optional
fallback_command, and whether termination of the target process is pre-authorized.
No need to invoke this skill when only viewing short command output or file contents.
Dependencies and installation
Install this skill:
npx skills add soia-team/soia-open-dev-ts-skills -g -a '*' -s soia-dev-terminal-ops -y
Hard dependencies: POSIX shell,ps、kill. The tmux workflow requires tmux. Network connectivity checks optionally use lsof; when missing, mark it as "network signal not checked" and do not use that to conclude deadlock.
Optional configuration:
~/.config/soia-skills/soia-dev-terminal-ops/config.yml
SOIA_DEV_TERMINAL_OPS_CONFIG_FILE=<custom-config-path>
Recommended configuration structure:
schema_version: 2
env:
TERMINAL_OPS_LOG_DIR: "<user-log-dir>"
TERMINAL_OPS_SESSION_NAME: "<session-name>"
TERMINAL_OPS_STALL_WINDOW_SECONDS: "<seconds>"
TERMINAL_OPS_TERM_GRACE_SECONDS: "<seconds>"
TERMINAL_OPS_FALLBACK_COMMAND: "<optional-command>"
Priority: this user input/CLI parameters → process environment → configuration file. Only use ${TMPDIR}when no log directory is given; if TMPDIR is also unset, first ask the user to specify a directory.
Logs and completion receipts
Report each time:
完成:<启动、诊断、恢复或终止结果>。
日志摘要:
- command/workdir: <命令与目录>
- session/pid: <会话名或 PID>
- log: <日志路径或“纯 stdout”>
- signals: <日志/CPU/网络/子进程证据>
- status: running / suspected-stall / inconclusive / completed / terminated / killed
验证:<退出码、复查命令和最后输出摘要>
问题与下一步:<fallback 或待确认项;没有则写“无”>
Trigger conditions
- Start or monitor commands expected to run for more than 30 seconds;
- Manage tmux sessions, background builds/tests, or continuous logs;
- Diagnose processes with no output, hanging tool calls, or an unrecoverable terminal;
- Terminate or downgrade long tasks under an explicit confirmation gate.
Parameter parsing
Parse and echo non-secret parameters before execution:
SESSION_NAME="${TERMINAL_OPS_SESSION_NAME:?set session name}"
LOG_DIR="${TERMINAL_OPS_LOG_DIR:-${TMPDIR:?set TERMINAL_OPS_LOG_DIR or TMPDIR}}"
STALL_WINDOW_SECONDS="${TERMINAL_OPS_STALL_WINDOW_SECONDS:?set observation window}"
TERM_GRACE_SECONDS="${TERMINAL_OPS_TERM_GRACE_SECONDS:?set TERM grace period}"
FALLBACK_COMMAND="${TERMINAL_OPS_FALLBACK_COMMAND:-}"
Verify that the session name contains only letters, digits, dots, underscores, or hyphens; show the resolved absolute path before creating directories. Do not hard-code agent names, executor states, timeout values, or log file names in the skill.
Command risk classification
Default read-only/idempotent:
tmux list-sessions
ps -o pid,ppid,stat,etime,time,command -p <PID>
tail -n <LINES> <LOG_FILE>
lsof -nP -p <PID> -i # 可选
High-impact actions must first state the target, basis, and data risk, and obtain user confirmation (or cite explicit pre-authorization in this request):
kill -TERM <PID>;kill -KILL <PID>;tmux kill-session -t <SESSION_NAME>;- Execute
FALLBACK_COMMAND, because it may incur costs, remote state changes, or duplicate work.
After confirming the PID, read the full command and parent PID again to avoid PID reuse or selecting the wrong process. Do not use broad pkill/killall instead of precise PID.
Background session management
The log name is specified by the caller and is not derived from the product name or agent name:
mkdir -p "$LOG_DIR"
LOG_FILE="$LOG_DIR/<log-name>.log"
tmux new-session -d -s "$SESSION_NAME" \
"cd '<workdir>' && <command> 2>&1 | tee '$LOG_FILE'"
tmux list-sessions
tmux capture-pane -p -t "$SESSION_NAME" -S -50
tail -n 50 "$LOG_FILE"
When commands, directories, or paths contain user input, use host tools to pass arguments safely; do not directly concatenate unchecked shell fragments. If a compound command must be run, first show the final command to the user exactly as it is.
Multi-signal stall diagnosis
S only indicates interruptible sleep; being in S for a long time may also be normal waiting. Elapsed time or a single timeout is never a kill condition.
At STALL_WINDOW_SECONDS check at least two sampling points covered:
- Log progress: whether the log mtime, size, or last business progress entry has changed; when there is no log, explicitly record the gap.
- CPU progress: whether cumulative CPU time has increased; a single low CPU reading only indicates idleness at that moment.
- Network/IPC progress: if the task depends on the network, check whether the connection exists and whether its state has changed;
lsofwhen unavailable, do not fabricate conclusions. - Child process progress: check whether child processes are still working, have exited, or are producing new output.
- Task-specific heartbeat: whether test counts, build targets, downloaded bytes, or queue counts, etc., have changed.
Only when "the observation window has exceeded the threshold" and at least two independent progress signals have continuously shown no change, and there is no reasonable explanation of normal waiting, mark it as suspected-stall. When signals are insufficient, mark it as inconclusive, continue observing, or ask the user to judge.
Example sampling (column names may differ slightly on macOS/Linux; interpret according to the actual output):
ps -o pid,ppid,stat,etime,time,command -p <PID>
wc -c < "$LOG_FILE"
tail -n 20 "$LOG_FILE"
lsof -nP -p <PID> -i 2>/dev/null || true
TARGET_PID=<PID>
ps -o pid,ppid,stat,etime,time,command -ax | awk -v p="$TARGET_PID" '$2 == p'
After waiting for the observation window configured by the user, resample and compute the difference. Do not mistakenly write "the command has not exited" as "no progress".
Safe termination and recovery
- Show the PID, full command, parent PID, working directory (when obtainable), and multi-signal evidence.
- Explain that TERM may interrupt writes, and KILL gives no chance to clean up; obtain confirmation.
- Send TERM.
- Within
TERM_GRACE_SECONDS, repeatedly recheck whether the process has exited, and check the log/disk-write status. - If it is still alive, show the recheck evidence and potential data loss, and obtain KILL confirmation again.
- Send KILL only to the same rechecked PID; then confirm that the process has disappeared, the session state, and output integrity.
- If a fallback is configured, first explain how context is passed, whether side effects and costs will be duplicated, and then execute after obtaining confirmation.
kill -TERM <PID>
# 按 TERM_GRACE_SECONDS 轮询:
ps -p <PID> >/dev/null 2>&1 || echo "terminated"
# 仍存活且再次确认后:
kill -KILL <PID>
ps -p <PID> >/dev/null 2>&1 && echo "still alive" || echo "killed"
Five categories of output files
| Category | Examples in this skill | Destination |
|---|---|---|
| A Temporary | Build/test logs and sampling snapshots for this round | User-specified log directory; otherwise ${TMPDIR}/soia-dev-terminal-ops/ |
| B Audit | Records of high-impact actions such as kill, session cleanup, and fallback | User-specified state directory or ${XDG_STATE_HOME}/soia-dev-terminal-ops/; if not configured, ask first |
| C Deliverable | Complete diagnostic package that the user requests to keep | Path explicitly specified by the user |
| D Product functionality as logs | Task logs defined by the target project | Only follow conventions already recorded by the target project; do not invent them in this skill |
| E Pure stdout | Short status checks, summaries that need not be retained | Do not write to disk |
The relative cwd must not be used as the default log directory. Category A may be rotated; Category B must not be deleted before the retention policy is confirmed.