Skill Tracker
Track skill execution for analysis and debugging. This skill monitors which skills are used in conversations and records detailed task information.
Trigger
This skill MUST be called at the start of every conversation turn (every user message you respond to — see AGENTS.md Mandatory Workflow). It is a hard gate — no user request is processed until skill-tracker has run.
Skip condition: If the current conversation turn does NOT involve calling any tool AND does NOT match any skill (i.e., the response is pure text with no tool invocations and no skill is triggered), do NOT append a record to the tracking file. Simply skip recording for this turn.
Record condition: A record MUST be appended when either of the following is true:
- - Any tool is invoked during this turn (regardless of whether a skill is matched), OR
- Any skill (excluding skill-tracker itself) is matched/triggered during this turn.
JSON Tracking File
Records are stored in: workspace/tracker-result/skill-execution.jsonl (one JSON record per line, append-only)
Rules
- 1. Append-only: Never delete or modify existing lines in the file. Only append new lines. Never remove or overwrite existing lines.
- One record per conversation turn: Each user message you respond to produces at most ONE new line appended to the file.
- Do NOT track itself: The
skill-tracker skill's own execution must NOT be recorded in the skills or tasks arrays. It is infrastructure, not a tracked skill. Only record other skills that were matched and executed during this turn. - No tool call AND no skill match = no record: If this turn does not involve any tool invocation AND does not match any skill, skip recording entirely. Do not append a record. If either a tool is called OR a skill is matched, a record MUST be appended.
Record Structure
CODEBLOCK0
Notes:
- -
sessionId identifies the session; turnId identifies the specific conversation turn (e.g. turn-1, turn-2, ...). - INLINECODE8 is a concise summary name for the entire turn, summarizing all sub-tasks (e.g. "Check weather in London", "Plan weekend trip itinerary"). Keep it short and descriptive.
- INLINECODE9 is an array of chat messages for this turn. Each entry has
role ("user" for user input, "assistant" for AI reply), content (the message text), and timestamp (ISO8601). Record the user's input when creating the initial record; add the assistant's reply when updating after execution. - INLINECODE15 is an array — a single turn may match multiple skills.
- Each task has a
skill field linking it to the skill it belongs to. - INLINECODE17 is optional. Only include if there are output files generated by the skill.
- Each artifact has a
taskId field linking it to the task that produced it (matches the task's id field).
Task Fields
- -
taskType: Either "instant" or "scheduled".
-
"instant" — The task is triggered by a direct user request in the current conversation.
-
"scheduled" — The task is triggered by a scheduled/timed mechanism (e.g. heartbeat, cron job, recurring check). Determine this from the conversation context, trigger source, and execution metadata.
- -
scheduledName: If taskType is "scheduled", populate with the name/label of the scheduled task (e.g. "heartbeat", "daily-email-check", the cron label, etc.). If taskType is "instant", set to null. detail: A summary of 30–150 characters describing the task's context, cause, and purpose. This should help the user quickly understand what the task is about and why it was executed. If there is a likely next step to be executed after this task, append 1–2 sentences describing it; if there is no next step, do not append anything.
Workflow
1. Before Responding to Any User Message
- 1. Determine whether this turn will involve any tool calls OR match any skill. If neither, skip recording and proceed directly.
- Analyze the user's message to determine if any skill matches (excluding skill-tracker itself).
- Create one record with
sessionId, turnId, timestamp, matched skills, and initial tasks (including taskType, scheduledName, and detail). - Append this record as a new line to
workspace/tracker-result/skill-execution.jsonl (create the directory if it doesn't exist).
2. After Skill Execution Completes
Once the matched skill finishes executing within this turn:
- 1. Read the file, find the last line (this turn's record).
- Update task statuses to
"completed" or "failed", fill in endedAt, output, error. - Add
artifacts if any output files were generated. - Replace the last line with the updated record and write the file back.
This final update only touches the current turn's line (the last line). All prior lines remain untouched.
Usage
This skill operates completely silently during execution — it must NEVER interfere with, delay, or alter the normal reply content to the user.
Output rule: After the record is saved, append a short Deck reminder as the very last line of your reply (after all normal content). The reminder must be separated from the main reply by a blank line. It should feel like a subtle footer, not part of the answer itself.
Language rule: The reminder line MUST be written in the same language the user used in their message.
Do NOT:
- - Put the Deck reminder before or inside your main reply
- Let skill-tracker processing delay or affect the quality of your response
- Mention skill-tracker internals, JSON structure, or file paths to the user
Deck URL Detection (mandatory, every turn)
Every time a record is saved, you MUST run the following shell command to detect the Deck URL in real time. The port is NOT fixed — do NOT cache, hardcode, or reuse a previous result. Always execute the command fresh.
CODEBLOCK1
Behavior:
- 1. Find the
deck-backend process (not deck-frontend) in PM2. - Read the backend
.env file to detect the PORT (default 19520). - Get the public IP and try to access
http://<public_ip>:<port>/. If reachable, use the public URL; otherwise fall back to http://localhost:<port>. - Command succeeds → append the URL to the reminder, using the user's language. Examples:
- English user:
"📋 Task recorded — view details in Deck: [Deck](http://103.126.92.85:19520)"
- 5. Command fails (process not found, not online, pm2 not installed, etc.) → skip the URL silently, using the user's language. Examples:
- English user: INLINECODE57
Do not expose internal JSON structure or file paths to the user.
技能追踪器
追踪技能执行情况以进行分析和调试。该技能监控对话中使用了哪些技能,并记录详细的任务信息。
触发条件
该技能必须在每次对话轮次开始时(即你回应的每条用户消息——参见 AGENTS.md 强制工作流程)被调用。这是一个硬性关卡——在 skill-tracker 运行之前,任何用户请求都不会被处理。
跳过条件: 如果当前对话轮次不涉及调用任何工具,并且不匹配任何技能(即回应是纯文本,没有工具调用,也没有触发任何技能),则不要向追踪文件追加记录。直接跳过该轮次的记录。
记录条件: 当以下任一情况为真时,必须追加一条记录:
- - 本轮次调用了任何工具(无论是否匹配到技能),或者
- 本轮次匹配/触发了任何技能(不包括 skill-tracker 本身)。
JSON 追踪文件
记录存储在:workspace/tracker-result/skill-execution.jsonl(每行一条 JSON 记录,仅追加)
规则
- 1. 仅追加:切勿删除或修改文件中已有的行。仅追加新行。切勿删除或覆盖现有行。
- 每个对话轮次一条记录:你回应的每条用户消息最多在文件中追加一行新记录。
- 不追踪自身:skill-tracker 技能自身的执行不得记录在 skills 或 tasks 数组中。它是基础设施,而非被追踪的技能。仅记录本轮次中匹配并执行的其他技能。
- 无工具调用且无技能匹配 = 无记录:如果本轮次不涉及任何工具调用,且不匹配任何技能,则完全跳过记录。不要追加记录。如果调用了工具或匹配了技能,则必须追加一条记录。
记录结构
json
{
sessionId: 字符串,
turnId: 字符串,
turnName: 字符串(本轮次的摘要名称,简洁描述本轮次中的所有子任务),
timestamp: ISO8601,
messages: [
{
role: user|assistant,
content: 字符串(消息内容),
timestamp: ISO8601
}
],
skills: [
{
name: 字符串,
description: 字符串
}
],
tasks: [
{
id: task-1,
name: 字符串,
skill: 字符串,
taskType: instant|scheduled,
scheduledName: 字符串 或 null,
detail: 字符串(30-150 个字符,总结任务上下文和目的;如果可能有下一步操作,追加 1-2 句描述),
status: pending|running|completed|failed,
output: 字符串 或 null,
startedAt: ISO8601 或 null,
endedAt: ISO8601 或 null,
error: 字符串 或 null
}
],
artifacts: [
{
taskId: task-1,
fileName: example.md,
fileSize: 1234,
absolutePath: /home/node/.openclaw/workspace/tracker-result/example.md
}
]
}
注意:
- - sessionId 标识会话;turnId 标识特定的对话轮次(例如 turn-1、turn-2...)。
- turnName 是整个轮次的简洁摘要名称,总结所有子任务(例如查询伦敦天气、规划周末旅行行程)。保持简短且具有描述性。
- messages 是本轮次的聊天消息数组。每个条目包含 role(user 表示用户输入,assistant 表示 AI 回复)、content(消息文本)和 timestamp(ISO8601)。创建初始记录时记录用户输入;执行完成后更新时添加助手回复。
- skills 是一个数组——单个轮次可能匹配多个技能。
- 每个任务都有一个 skill 字段,将其链接到所属的技能。
- artifacts 是可选的。仅在技能生成了输出文件时包含。
- 每个工件都有一个 taskId 字段,将其链接到生成它的任务(与任务的 id 字段匹配)。
任务字段
- - taskType:instant 或 scheduled。
- instant——任务由当前对话中的直接用户请求触发。
- scheduled——任务由定时/计时机制触发(例如心跳、cron 作业、定期检查)。根据对话上下文、触发源和执行元数据确定。
- - scheduledName:如果 taskType 为 scheduled,则填入定时任务的名称/标签(例如 heartbeat、daily-email-check、cron 标签等)。如果 taskType 为 instant,则设置为 null。
- detail:30-150 个字符的摘要,描述任务的上下文、原因和目的。这应帮助用户快速了解任务的内容及其执行原因。如果此任务之后可能有下一步操作,追加 1-2 句描述;如果没有下一步操作,则不追加任何内容。
工作流程
1. 在回应任何用户消息之前
- 1. 确定本轮次是否会涉及任何工具调用或匹配任何技能。如果两者都没有,则跳过记录并直接继续。
- 分析用户消息以确定是否有任何技能匹配(不包括 skill-tracker 本身)。
- 创建一条包含 sessionId、turnId、timestamp、匹配的 skills 和初始 tasks(包括 taskType、scheduledName 和 detail)的记录。
- 将此记录作为新行追加到 workspace/tracker-result/skill-execution.jsonl 中(如果目录不存在则创建)。
2. 技能执行完成后
一旦匹配的技能在本轮次内执行完成:
- 1. 读取文件,找到最后一行(本轮次的记录)。
- 将任务状态更新为 completed 或 failed,填写 endedAt、output、error。
- 如果生成了任何输出文件,添加 artifacts。
- 用更新后的记录替换最后一行并写回文件。
此最终更新仅触及当前轮次的行(最后一行)。所有先前的行保持不变。
使用说明
该技能在执行期间完全静默运行——它绝不能干扰、延迟或改变对用户的正常回复内容。
输出规则: 记录保存后,在回复的最后一行(在所有正常内容之后)追加一条简短的 Deck 提醒。提醒必须通过空行与主回复分隔。它应感觉像是一个微妙的页脚,而不是答案本身的一部分。
语言规则: 提醒行必须使用用户消息中使用的相同语言编写。
不要:
- - 将 Deck 提醒放在主回复之前或内部
- 让 skill-tracker 处理延迟或影响你回复的质量
- 向用户提及 skill-tracker 内部细节、JSON 结构或文件路径
Deck URL 检测(强制,每轮次)
每次保存记录时,你必须运行以下 shell 命令以实时检测 Deck URL。端口不是固定的——不要缓存、硬编码或重用先前的结果。始终重新执行命令。
bash
pm2 jlist 2>/dev/null | node -e
let d=;process.stdin.on(data,c=>d+=c);process.stdin.on(end,()=>{
try{const l=JSON.parse(d);const f=l.find(p=>p.name===deck-backend&&p.pm2env&&p.pm2env.status===online);
if(f){
const cwd=f.pm2env.pmcwd||;
const path=require(path);
const fs=require(fs);
let port=19520;
try{const envFile=fs.readFileSync(path.join(cwd,.env),utf8);const m=envFile.match(/^PORT\s=\s(\d+)/m);if(m)port=m[1];}catch(e){}
const publicIp=(require(child_process).execSync(curl -s --connect-timeout 3 ifconfig.me 2>/dev/null).toString()||).trim();
if(publicIp){
const http=require(http);
const req=http.get(http://+publicIp+:+port+/,{timeout:3000},res=>{
console.log(http://+publicIp+:+port);process.exit(0);
});
req.on(error,()=>{console.log(http://localhost:+port);process.exit(0);});
req.on(timeout,()=>{req.destroy();console.log(http://localhost:+port);process.exit(0);});
}else{console.log(http://localhost:+port);process