dev-log
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDev Log
Dev Log
将前端代码的 console.log 输出通过 HTTP 接口实时发送,让 AI 能够自动获取运行时日志,无需用户手动复制控制台内容。
核心理念: 大多数 console.log 都是为了让 AI 查看结果,因此应该默认使用 dev-log 方式,除非是非常简单的临时调试。
Send console.log outputs from frontend code in real-time via HTTP interface, enabling AI to automatically obtain runtime logs without users manually copying console content.
Core Concept: Most console.log statements are intended for AI to view results, so dev-log should be used by default unless it's a very simple temporary debugging scenario.
When to Use
When to Use
AI 应该主动判断并使用此技能的情况:
- 生成前端代码时 - 如果生成的代码可能需要调试/验证,默认使用 dev-log 收集日志
- 用户说"帮我调试"、"有问题"、"看看为什么" - 需要查看运行时状态时
- 需要追踪异步流程 - fetch、Promise、async/await 的执行过程
- 需要验证逻辑 - 表单验证、状态更新、条件判断等
- 需要查看变量值 - 特别是动态生成或用户输入的值
- 用户说"操作完成了"、"你看下"、"好了" - 提示用户已完成操作,AI 应该读取日志
不需要使用的情况:
- 纯静态内容生成(如 HTML 模板)
- 非常简单的一次性验证
- 用户明确表示不需要调试
- 代码完全是后端的(Node.js 服务端)
Situations where AI should proactively decide to use this skill:
- When generating frontend code - If the generated code may require debugging/validation, use dev-log to collect logs by default
- When the user says "help me debug", "there's a problem", "see why" - When runtime status needs to be checked
- When tracking asynchronous processes is needed - Execution processes of fetch, Promise, async/await
- When logic validation is required - Form validation, state updates, conditional judgments, etc.
- When variable values need to be viewed - Especially dynamically generated or user-input values
- When the user says "operation completed", "check this", "done" - Indicates the user has finished operations, AI should read the logs
Situations where it's not needed:
- Pure static content generation (e.g., HTML templates)
- Very simple one-time validation
- The user explicitly states no debugging is needed
- The code is entirely backend (Node.js server-side)
Examples
Examples
Example 1: 主动启用 - AI 判断需要调试
Example 1: Active Enablement - AI judges debugging is needed
markdown
User: 写一个 React 计数器组件
Agent: 我来创建一个计数器组件,并添加日志以便验证功能正常。
[启动 dev-log 服务,生成 sessionId: sess_8x7k2p]
```jsx
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_8x7k2p',time:new Date().toTimeString().split(' ')[0],type:'before-increment',data:{count}})}).catch(()=>{});
setCount(c => c + 1);
};
return <button onClick={increment}>Count: {count}</button>;
}请点击按钮几次,然后告诉我结果。
User: 点了3次
Agent: [读取日志]
从日志看到:
- count 从 0 → 1 → 2 → 3
- 每次 increment 都正确执行
计数器工作正常!
undefinedmarkdown
User: Write a React counter component
Agent: I'll create a counter component and add logs to verify the functionality works properly.
[Start dev-log service, generate sessionId: sess_8x7k2p]
```jsx
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_8x7k2p',time:new Date().toTimeString().split(' ')[0],type:'before-increment',data:{count}})}).catch(()=>{});
setCount(c => c + 1);
};
return <button onClick={increment}>Count: {count}</button>;
}Please click the button a few times and let me know the result.
User: Clicked 3 times
Agent: [Read logs]
From the logs:
- count changed from 0 → 1 → 2 → 3
- Each increment executed correctly
The counter is working properly!
undefinedExample 2: 追踪异步请求
Example 2: Track Asynchronous Requests
markdown
User: 这个异步函数有时候会失败,帮我看看
Agent: [uses dev-log skill] 启动日志服务...
```javascript
async function fetchData(userId) {
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_a1b2c3',time:new Date().toTimeString().split(' ')[0],type:'fetch-start',data:{userId}})}).catch(()=>{});
try {
const response = await fetch(`/api/users/${userId}`);
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_a1b2c3',time:new Date().toTimeString().split(' ')[0],type:'fetch-response',data:{status:response.status,ok:response.ok}})}).catch(()=>{});
if (!response.ok) {
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_a1b2c3',time:new Date().toTimeString().split(' ')[0],type:'fetch-error',data:{status:response.status}})}).catch(()=>{});
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_a1b2c3',time:new Date().toTimeString().split(' ')[0],type:'fetch-success',data:{hasData:!!data}})}).catch(()=>{});
return data;
} catch (error) {
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_a1b2c3',time:new Date().toTimeString().split(' ')[0],type:'catch-error',data:{message:error.message}})}).catch(()=>{});
throw error;
}
}操作一下,告诉我结果。
User: 还是失败
Agent: [读取日志]
日志显示:
- fetch-start ✓
- fetch-response {status: 404, ok: false}
- fetch-error
问题是返回 404,说明 API 端点 不存在。需要检查后端路由配置...
/api/users/${userId}undefinedmarkdown
User: This async function sometimes fails, help me check it
Agent: [uses dev-log skill] Starting log service...
```javascript
async function fetchData(userId) {
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_a1b2c3',time:new Date().toTimeString().split(' ')[0],type:'fetch-start',data:{userId}})}).catch(()=>{});
try {
const response = await fetch(`/api/users/${userId}`);
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_a1b2c3',time:new Date().toTimeString().split(' ')[0],type:'fetch-response',data:{status:response.status,ok:response.ok}})}).catch(()=>{});
if (!response.ok) {
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_a1b2c3',time:new Date().toTimeString().split(' ')[0],type:'fetch-error',data:{status:response.status}})}).catch(()=>{});
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_a1b2c3',time:new Date().toTimeString().split(' ')[0],type:'fetch-success',data:{hasData:!!data}})}).catch(()=>{});
return data;
} catch (error) {
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_a1b2c3',time:new Date().toTimeString().split(' ')[0],type:'catch-error',data:{message:error.message}})}).catch(()=>{});
throw error;
}
}Perform the operation and let me know the result.
User: It still fails
Agent: [Read logs]
Logs show:
- fetch-start ✓
- fetch-response {status: 404, ok: false}
- fetch-error
The problem is a 404 response, which means the API endpoint does not exist. Need to check backend route configuration...
/api/users/${userId}undefinedExample 3: 表单验证追踪
Example 3: Form Validation Tracking
markdown
User: 写一个登录表单的验证逻辑
Agent: [启动 dev-log,生成 sessionId: sess_valid9]
```javascript
function validateLoginForm(form) {
const email = form.email.value;
const password = form.password.value;
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_valid9',time:new Date().toTimeString().split(' ')[0],type:'validate-input',data:{field:'email',value:email}})}).catch(()=>{});
const errors = {};
if (!email) {
errors.email = '邮箱不能为空';
}
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_valid9',time:new Date().toTimeString().split(' ')[0],type:'validate-result',data:{field:'email',valid:!!email}})}).catch(()=>{});
// ... 更多验证
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_valid9',time:new Date().toTimeString().split(' ')[0],type:'final-result',data:{errorCount:Object.keys(errors).length}})}).catch(()=>{});
return { valid: Object.keys(errors).length === 0, errors };
}测试后告诉我结果,我会根据日志判断验证逻辑是否正确。
undefinedmarkdown
User: Write validation logic for a login form
Agent: [Start dev-log, generate sessionId: sess_valid9]
```javascript
function validateLoginForm(form) {
const email = form.email.value;
const password = form.password.value;
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_valid9',time:new Date().toTimeString().split(' ')[0],type:'validate-input',data:{field:'email',value:email}})}).catch(()=>{});
const errors = {};
if (!email) {
errors.email = '邮箱不能为空';
}
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_valid9',time:new Date().toTimeString().split(' ')[0],type:'validate-result',data:{field:'email',valid:!!email}})}).catch(()=>{});
// ... More validation
fetch('http://localhost:54321',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'sess_valid9',time:new Date().toTimeString().split(' ')[0],type:'final-result',data:{errorCount:Object.keys(errors).length}})}).catch(()=>{});
return { valid: Object.keys(errors).length === 0, errors };
}Test it and let me know the result, I'll judge if the validation logic is correct based on the logs.
undefinedImplementation
Implementation
服务启动
Service Startup
启动命令:
bash
cd skills/dev-log && ./start.sh启动脚本会自动:
- 检查现有服务状态(读取 并测试连接)
port.txt - 如果服务正常运行,则复用现有服务
- 如果服务异常或不存在,则启动新服务
- 服务启动后会记录端口到 ,进程 ID 到
port.txtpid.txt
文件结构:
./skills/dev-log/
├── start.sh # 启动脚本(检查/启动服务)
├── read-log.sh # 读取日志脚本(支持过滤)
├── server.js # HTTP 服务器(ESM 模块)
├── pid.txt # 服务进程 ID
├── port.txt # 服务端口
└── dev-logs.json # 日志文件(JSON 格式)Startup Command:
bash
cd skills/dev-log && ./start.shThe startup script will automatically:
- Check existing service status (read and test connection)
port.txt - Reuse the existing service if it's running normally
- Start a new service if the existing one is abnormal or non-existent
- Record the port to and process ID to
port.txtafter service startuppid.txt
File Structure:
./skills/dev-log/
├── start.sh # Startup script (check/start service)
├── read-log.sh # Log reading script (supports filtering)
├── server.js # HTTP server (ESM module)
├── pid.txt # Service process ID
├── port.txt # Service port
└── dev-logs.json # Log file (JSON format)日志读取
Log Reading
读取所有日志:
bash
./skills/dev-log/read-log.sh按 sessionId 过滤日志:
bash
./skills/dev-log/read-log.sh "$SESSION_ID"Read all logs:
bash
./skills/dev-log/read-log.shFilter logs by sessionId:
bash
./skills/dev-log/read-log.sh "$SESSION_ID"代码生成模板
Code Generation Template
标准 fetch 请求模板:
javascript
fetch('http://localhost:PORT',{
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({
sessionId:'SESSION_ID',
time:'TIME',
type:'TYPE',
data:DATA
})
}).catch(()=>{})单行简化版本:
javascript
fetch('http://localhost:PORT',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'SID',time:'TIME',type:'TYPE',data:DATA})}).catch(()=>{})模板变量说明:
- : 从
PORT读取的端口号skills/dev-log/port.txt - : AI 生成的会话 ID(格式:
SESSION_ID+ 8位随机字符)sess_ - : 时间戳(如
TIME或14:23:05)new Date().toTimeString().split(' ')[0] - : 日志类型(建议:
TYPE/state/error/validation/request/response等)fetch-start - : 要记录的任意数据对象
DATA
Standard fetch request template:
javascript
fetch('http://localhost:PORT',{
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({
sessionId:'SESSION_ID',
time:'TIME',
type:'TYPE',
data:DATA
})
}).catch(()=>{})Simplified single-line version:
javascript
fetch('http://localhost:PORT',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'SID',time:'TIME',type:'TYPE',data:DATA})}).catch(()=>{})Template Variable Explanation:
- : Port number read from
PORTskills/dev-log/port.txt - : Session ID generated by AI (format:
SESSION_ID+ 8 random characters)sess_ - : Timestamp (e.g.,
TIMEor14:23:05)new Date().toTimeString().split(' ')[0] - : Log type (recommended:
TYPE/state/error/validation/request/responseetc.)fetch-start - : Any data object to be recorded
DATA
完整使用流程
Complete Usage Flow
- AI 判断需要调试 → 自动启动 dev-log 技能
- 检查/启动服务 → 测试现有服务或启动新服务
- 生成 sessionId → 在内存中记住,格式
sess_xxxxxxxx - 清空日志 → 新一轮调试开始时
- 读取端口号 → 从 获取
port.txt - 生成带日志的代码 → 在关键位置插入 fetch 语句
- 提示用户操作 → "请操作一下,然后告诉我结果"
- 用户告知完成 → "好了"、"操作完成了"
- 读取并分析日志 → 按 sessionId 过滤,分析结果
- AI judges debugging is needed → Automatically start the dev-log skill
- Check/start service → Test existing service or start a new one
- Generate sessionId → Store in memory, format
sess_xxxxxxxx - Clear logs → At the start of a new debugging round
- Read port number → Obtain from
port.txt - Generate code with logs → Insert fetch statements at key positions
- Prompt user to operate → "Please perform the operation and let me know the result"
- User notifies completion → "Done", "Operation completed"
- Read and analyze logs → Filter by sessionId, analyze results
多会话隔离
Multi-Session Isolation
- 每个 AI 会话有独立的 sessionId(内存中)
- 日志都写入同一个
dev-logs.json - AI 读取日志时用自己的 sessionId 过滤
- 格式:
{"sessionId":"sess_abc123","time":"14:23:05","type":"state","data":{...}}
- Each AI session has an independent sessionId (stored in memory)
- All logs are written to the same
dev-logs.json - AI filters logs using its own sessionId when reading
- Format:
{"sessionId":"sess_abc123","time":"14:23:05","type":"state","data":{...}}
注意事项
Notes
- 默认使用 - 生成前端代码时默认考虑使用 dev-log,除非非常简单
- 清理时机 - 新一轮调试开始时清空日志
- 生产环境 - 务必移除调试代码
- 错误处理 - fetch 必须加 避免阻塞主逻辑
.catch(()=>{}) - 单行插入 - 日志代码在用户代码的下一行插入,保持原代码结构
- 本地开发 - 仅用于本地开发,不要暴露到公网
- Default Usage - Consider using dev-log by default when generating frontend code, unless it's extremely simple
- Cleanup Timing - Clear logs at the start of a new debugging round
- Production Environment - Be sure to remove debugging code
- Error Handling - Fetch must include to avoid blocking main logic
.catch(()=>{}) - Single-Line Insertion - Insert log code on the line below the user's code to preserve original code structure
- Local Development - Only for local development, do not expose to public network