Skip to content
Back to skills

Worklog

ASecurity

记录本周做了什么(CC+Codex+ZCode+MiniMax Code 四源、主动梳理+随手记录双模式),一键生成"需求叙事"周报。触发词:"记录一下"、"梳理一下最近做了什么"、"周报"、"汇报"、"产出"、"站会"。数据存 报告文档/需求/日志 与 报告文档/需求/周报。

  • 2 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 1, 2026
ai-agentspythonbashsql

Works with

  • claude code
  • cursor
  • cli

Security analysis

A100/100

Pro scans all 7 files and shows the line behind each finding

Scanned October 1, 2026

npx -y skills add 2021291696/worklog-alllog --skill worklog --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Worklog?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Worklog
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/2021291696-worklog/badge)](https://www.skillsdirectory.com/skills/2021291696-worklog)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: worklog
description: 记录本周做了什么(CC+Codex+ZCode+MiniMax Code 四源、主动梳理+随手记录双模式),一键生成"需求叙事"周报。触发词:"记录一下"、"梳理一下最近做了什么"、"周报"、"汇报"、"产出"、"站会"。数据存 报告文档/需求/日志 与 报告文档/需求/周报。
---

# worklog 工作产出记录·汇报

记录本周做了什么(会话自动挖:CC/Codex/ZCode/MiniMax Code + 随手主动记),一键生成给别人看的"需求叙事"周报。纯原生工具,无脚本依赖。

## 闸口铁律(最高优先级,覆盖一切执行惯性)

以下闸口必须**停轮等待**:展示选项/候选后**立即结束本轮回复**,用户未回复前禁止任何扫描、提炼、落盘、派 agent:

| 闸口 | 时机 |
|------|------|
| ① 模式选择 | 裸调用 `/worklog` 且用户没说要做哪个 |
| ② 日期范围 | 模式 A 第 1 步;汇报第 3 步 |
| ③ 条目/清单确认 | 模式 A 第 4 步;汇报第 6 步 |

- **禁止自问自答**:同一回合内提出问题又自行回答并继续执行 = 违规(实测 Claude 会把"先问"叙述出来然后自己答掉一路跑完)。
- 回答含糊("都行""好""随便")≠ 明确选择,必须再问;**无确认 = 0 条写入**,绝不默认全选。

裸调用 `/worklog`(无参数、未指向任何模式)→ 先闸口①问:"随手记 / 梳理最近做了什么 / 出周报?"。用户话里已明确指向时直接进入:"记录一下:…"→模式 B;"梳理一下"→模式 A;"周报/汇报/产出/站会"→汇报。

## 存储布局

周粒度,以**本周周一日期**命名(周一为一周起始):

```
报告文档/需求/
├── 日志/<周一日期>.md        # 主动记录流水,只追加从不覆盖
└── 周报/
    ├── md形式/<起点日期>.md    # md 周报快照,可重复生成
    └── word形式/<起点日期>.docx # Word 版周报(导出时生成)
```

### 周起算

```bash
DOW=$(date +%u)                                  # 1=周一 ... 7=周日
MONDAY=$(date -d "$(date +%F) -$((DOW-1)) days" +%F)   # 本周一
```

`<周一日期>` 即 `$MONDAY`。周内任意调用都用它定位同一份文件。

### 上次搜索断点

模式 A 与汇报的日期范围选项「从上次搜索-现在」依赖一个断点文件:

```
报告文档/需求/.last-scan    # 一行,YYYY-MM-DD,= 上次执行会话扫描当天的日期
```

- **写入时机**:模式 A 第 2 步四源扫描完成后、汇报第 3 步四源挖完后,执行 `date +%F > 报告文档/需求/.last-scan`。只记录"扫描动作发生的日期",与本次扫描选的范围起点无关。
- **读取**:用户选「从上次搜索-现在」时 `$START=$(cat 报告文档/需求/.last-scan 2>/dev/null)`;文件不存在或为空 → 告知无上次搜索记录,重新展示其余选项(仍在闸口②停轮语义内)。
- 断点按天粒度衔接:上次扫描当天的新会话会被重扫一次,由「去重」小节兜底跳过,不产生重复条目。

## 数据源

| 源 | 路径 | 时间基准 |
|----|------|---------|
| CC | `~/.claude/projects/**/*.jsonl` | JSONL 内 `"timestamp"`(UTC) |
| Codex | `~/.codex/sessions/YYYY/MM/DD/*.jsonl` + `archived_sessions/` 兜底 | 目录/文件名(本地时间) |
| ZCode | `~/.zcode/cli/db/db.sqlite`(SQLite:`session`/`message`/`part` 三表) | `session.time_updated`(epoch 毫秒,绝对时间) |
| MiniMax Code | `~/.minimax/v2/sessions/YYYY/MM/DD/HH-MM-SS-mmm-session_*/messages.jsonl` | 行内 `message.timestamp`(epoch 毫秒,绝对时间) |

### 时区归一(重要,防边界日漏记录)
- CC `timestamp` 是 UTC(如 `2026-08-12T02:00:00.000Z`,本地 UTC+8 → 08-12 10:00)。
- 按日期过滤"本周/起点之后"前,统一把 CC timestamp 转本地再比较(`date -d "<TS>" +%F`)。
- 否则周一 00:00–07:59 落地的 UTC 记录(仍是上周日期)会被漏掉。
- Codex 目录/文件名已是本地时间,直接比较。
- ZCode 时间戳是 epoch 毫秒(绝对时间),无时区换算问题:起点转毫秒 `$START_MS=$(( $(date -d "$START 00:00:00" +%s) * 1000 ))` 后直接比较。
- MiniMax Code 时间戳同为 epoch 毫秒,无换算问题,比较方式同 ZCode;**不要用目录名日期过滤**(跨天长会话会漏,须用消息内末条 timestamp 判断)。

## ZCode 会话查询(SQLite)

ZCode 会话存在 SQLite 库里,**必须只读打开**(ZCode 运行时正占用该库,`mode=ro` 与 WAL 并发安全,已实测):

```bash
START_MS=$(( $(date -d "$START 00:00:00" +%s) * 1000 ))   # $START=起点日期 YYYY-MM-DD
python - "$START_MS" <<'EOF'
import sqlite3, json, sys, os, datetime, pathlib
db = os.path.expanduser('~/.zcode/cli/db/db.sqlite')
con = sqlite3.connect(pathlib.Path(db).as_uri() + '?mode=ro', uri=True)
cur = con.cursor()
for sid, title, d, tc in cur.execute(
    "SELECT id, title, directory, time_created FROM session "
    "WHERE time_updated >= ? ORDER BY time_created", (sys.argv[1],)).fetchall():
    print(f"== {datetime.datetime.fromtimestamp(tc/1000):%m-%d %H:%M}  {title or '(无标题)'}  [{d}]")
    for (p,) in cur.execute("""SELECT p.data FROM part p JOIN message m ON p.message_id = m.id
        WHERE p.session_id = ? AND json_extract(m.data,'$.role') = 'user'
          AND json_extract(p.data,'$.type') = 'text'
          AND COALESCE(json_extract(p.data,'$.synthetic'), 0) = 0
        ORDER BY p.time_created""", (sid,)):
        t = json.loads(p).get('text', '').strip()
        if t: print('  U>', t[:120].replace('\n', ' '))
    tools = cur.execute("""SELECT DISTINCT json_extract(data,'$.tool') FROM part
        WHERE session_id = ? AND json_extract(data,'$.type') = 'tool'""", (sid,)).fetchall()
    print('  tools:', ', '.join(sorted(str(t[0]) for t in tools if t[0])))
EOF
```

- `~/.zcode/cli/db/db.sqlite` 不存在 → 跳过该源并提示。
- `session.title` 由 CLI 维护(`title_source` 字段),质量可靠,可直接作会话主题(不像 CC 的 thread_name 实测多为"你好")。
- `synthetic=1` 的 part 是系统注入(如 TodoWrite 提醒),不是真实用户输入,查询已排除。
- 仓库里 `scripts/zcode_sessions.py` 是同一条查询的可执行副本(`python scripts/zcode_sessions.py <START_MS> [db]`),单测直接驱动它。

## MiniMax Code 会话查询

MiniMax Code(ZCode 系内核)会话按日期分层存 `~/.minimax/v2/sessions/YYYY/MM/DD/HH-MM-SS-mmm-session_*/`,核心是 `messages.jsonl`,每行一个消息对象:`message.role`(user/assistant)+ `message.content[]`(text 块)+ `message.timestamp`(epoch 毫秒)。扫描脚本:

```bash
START_MS=$(( $(date -d "$START 00:00:00" +%s) * 1000 ))   # $START=起点日期 YYYY-MM-DD
python - "$START_MS" <<'EOF'
import json, glob, os, sys, datetime
sys.stdout.reconfigure(encoding='utf-8')   # 必须:Windows 下中文输出防 GBK 乱码
START_MS = int(sys.argv[1])
SKIP_PREFIX = ('<system-reminder', 'Base directory for this skill', 'This is a skill', '<background-task-finished', '[Request interrupted')
for f in sorted(glob.glob(os.path.expanduser('~/.minimax/v2/sessions/*/*/*/*-session_*/messages.jsonl'))):
    last_ms = 0; msgs = []
    for line in open(f, encoding='utf-8', errors='ignore'):
        try: o = json.loads(line)
        except: continue
        m = o.get('message') or {}
        ts = m.get('timestamp')
        if ts: last_ms = max(last_ms, ts)                      # 全文件末条,跨天会话不漏
        if m.get('role') != 'user': continue
        c = m.get('content', [])
        if not isinstance(c, list): continue
        for x in c:
            if isinstance(x, dict) and x.get('type') == 'text':
                t = x.get('text', '').strip()
                if t and not t.startswith(SKIP_PREFIX): msgs.append(t)
    if not msgs or last_ms < START_MS: continue                # msgs 空 = 纯注入会话,跳过
    print(f"{datetime.datetime.fromtimestamp(last_ms/1000):%Y-%m-%d}  {f}  {msgs[0][:80]}")
EOF
```

- **时间基准是消息内 `timestamp`,不是目录名日期**(目录名是会话创建时刻,跨天长会话按它过滤会漏掉末条之后的日期)。
- `<system-reminder>`/skill 注入开头的 user 消息是系统注入不是真实输入,脚本已排除;全被排除的会话跳过。
- `manifest.json` 有 `createdAtMs`/`updatedAtMs` 但**无标题与工作目录**,会话主题只能用首条真实用户消息。
- `~/.minimax/` 不存在 → 跳过该源并提示。

## 记录 · 模式 B:随手记录

触发词:"记录一下:..."、"记一下:..."。零摩擦,用户说啥记啥。

1. 计算本周一 `$MONDAY`(见"周起算")。
2. 定位 `报告文档/需求/日志/$MONDAY.md`,不存在则创建(含目录)。
3. 以当天日期 `MM-DD` 分节,追加 `- [需求] <一句话>`。格式:

```markdown
## 08-12
- [记住我] 设计了登录勾选逻辑 + 30 天 token 续期
```

4. 当天节已存在则在其下追加;**只追加,绝不覆盖或改动历史条目**。

## 记录 · 模式 A:主动梳理

触发词:"梳理一下最近做了什么"、"梳理一下"。在功能完成/阶段性完成时使用。

1. **选日期范围(闸口②,硬停轮)**:展示下列选项后立即结束本轮回复,用户明确选择后再扫描:
   - A. 本周一-现在(默认)——本周已有日志时起点取日志最后一个 `## MM-DD` 节,跳过已记录项
   - B. 七天前-现在
   - C. 从上次搜索-现在——起点读「上次搜索断点」(见「上次搜索断点」小节);无断点记录时告知用户"没有上次搜索记录"并重新展示其余选项等其选择
   - D. 自定义——向用户要起止日期
2. **扫最近会话**:
   - CC:`~/.claude/projects/**/*.jsonl`,按 JSONL 内 `"timestamp"`(转本地时区)筛选 ≥ 起点。
   - Codex:`~/.codex/sessions/YYYY/MM/DD/*.jsonl`(本地时间)+ `archived_sessions/` 兜底,目录/文件名日期 ≥ 起点。`~/.codex/` 不存在则跳过该源并提示。
   - ZCode:`~/.zcode/cli/db/db.sqlite` 按「ZCode 会话查询」小节执行,`time_updated >= $START_MS` 筛选。库不存在则跳过该源并提示。
   - MiniMax Code:`~/.minimax/v2/sessions/*/*/*/*-session_*/messages.jsonl` 按「MiniMax Code 会话查询」小节执行,消息内 timestamp(epoch 毫秒)≥ `$START_MS` 筛选。目录不存在则跳过该源并提示。
   - 四源扫完后执行「上次搜索断点」小节的写入动作。
3. **提炼候选(仅供展示,禁止直接落盘)**:轻读每个会话的用户消息/工具调用,产出**编号**列表 `1. 日期 + 主题 + 2-3 要点`(不依赖 `session_index.jsonl` 的 thread_name,实测多为"你好";ZCode 会话可直接用 `session.title` 作主题)。用户消息里可能贴过密钥/token/密码(实测存在),候选与落盘一律脱敏或省略,敏感串不得出现在任何输出中。
4. **用户确认(闸口③,硬停轮,必须精确到条目)**:展示编号候选 + "要记哪几条?"(如"记 1、3"或"只记第 2 条")后立即结束本轮回复。**用户未明确选择的条目,一律不得写入。** 回答含糊("都行""好")≠ 选择,必须再次询问,不得默认全选。
5. **落盘(只写用户确认的条目)**:严格按用户确认的编号/条目,逐条按模式 B 格式追加到 `报告文档/需求/日志/$MONDAY.md`。落盘后回执:"已写入 N 条:<条目列表>";未写入的候选列出提醒(可改天再记)。

## 去重与防丢失

### 去重(两种模式落盘前都执行)
1. 读 `报告文档/需求/日志/$MONDAY.md` 现有条目,提取所有 `[需求名]` 标签(`- [XX] ...`)。
2. 新条目 `[需求名]` 已存在 → 跳过并提示"该需求已记录,跳过",不重复追加。
3. 语义相近但标签不同 → 模式 A 由用户确认时人工去重;模式 B 提示用户"是否合并到已有条目"。

### 防丢失
- 日志文件**只追加从不覆盖**;生成周报只写 `周报/`,绝不改动 `日志/`。
- 模式 A 定期(阶段完成时)捞会话兜底,与随手记录互为备份。

## 汇报(触发词:周报 / 汇报 / 产出 / 站会)

1. 计算本周一 `$MONDAY`。
2. 读 `报告文档/需求/日志/$MONDAY.md`(主动记录)。
3. **询问日期范围(闸口②,硬停轮)**:展示 A. 本周一-现在(默认)/ B. 七天前-现在 / C. 从上次搜索-现在(无断点记录时说明并重新展示其余选项)/ D. 自定义后立即结束本轮回复;用户明确选择后再按所选范围挖四源会话:CC(timestamp 转本地后属所选范围)+ Codex(目录日期 ≥ 所选起点)+ ZCode(db.sqlite 按「ZCode 会话查询」,`time_updated` ≥ 起点)+ MiniMax Code(messages.jsonl 按「MiniMax Code 会话查询」,timestamp ≥ 起点)。任一源探测不到则跳过并提示。四源挖完后执行「上次搜索断点」小节的写入动作。选定后记扫描起点 `$START`(周报文件名据此):
   - A → `$START=$MONDAY`
   - B → `$START=$(date -d "-6 days" +%F)`(含今天共 7 天)
   - C → `$START=` 断点文件里存的日期
   - D → `$START=` 用户给的起始日期
4. 并行派 4 个轻量 agent(Claude Code 内用 haiku;ZCode 内用其子代理机制。契约见 `references/agent-team-contract.md`):Agent-CC → `md形式/$START-cc-draft.md`;Agent-Codex → `md形式/$START-codex-draft.md`;Agent-Zcode → `md形式/$START-zcode-draft.md`;Agent-Minimax → `md形式/$START-minimax-draft.md`。某源本次被跳过时不派对应 agent,不产出空草稿。
5. 主线程合成草案(暂不落盘):主动记录 + 各源草稿 → 按"需求叙事"模板整理出完整周报内容,附"将写入 N 条需求"的编号清单(每条一句话)。
6. **清单确认(闸口③,硬停轮)**:展示编号清单,问"全部写入,还是删掉哪几条?"后立即结束本轮回复。用户确认后才写入;点名删除的条目剔除;含糊回答必须再问,无确认不写。
7. 写入 `报告文档/需求/周报/md形式/$START.md`,随后删除全部中间草稿(`$START-cc-draft.md`、`$START-codex-draft.md`、`$START-zcode-draft.md`、`$START-minimax-draft.md` 等本次实际产出的),`md形式/` 只留最终周报。
8. 触发词含"站会/晨会" → 末尾附 Scrum 三问(完成/计划/阻塞)。

### 需求叙事模板

```markdown
# 产出汇报(<起点> ~ <终点>)

## 需求:<需求名>
- **需求背景**:<为什么做>
- **方案**:<怎么设计>
- **落地**:<实际做了啥>
- **结果**:<数据/效果;缺失标"待补充",禁止编造>
```

9. 输出后告知:日期、周报路径、本周有无记录/会话。无记录无会话时提示先"记录一下"或"梳理一下"。
10. 询问用户是否需要把周报导出 Word。需要则查本地 docx 相关 skill(Claude Code 双路径 `~/.claude/skills/` + `.claude/skills/`;ZCode 内用 Skill 工具的 `docx` / `document-skills:docx`),调用它把 `报告文档/需求/周报/md形式/$START.md` 转成 Word,输出到 `报告文档/需求/周报/word形式/$START.docx`;查不到则告知用户并询问替代方案。

Files in this skill

  • SKILL.md15.1 KB
  • references/agent-team-contract.md1.4 KB
  • scripts/zcode_sessions.py2.2 KB
  • test/fixtures/fake-cc-session.jsonl232 B
  • test/fixtures/fake-codex-session.jsonl279 B
  • test/fixtures/fake-log-2026-08-10.md73 B
  • test/test-worklog.md1.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.