根据 Git 提交记录 + Teambition 任务数据,AI 推断并填写 Teambition 工时。当用户说「填工时」「登记工时」「填今天的工时」时使用本 skill。
---
name: teambition-worklog
description: "根据 Git 提交记录 + Teambition 任务数据,AI 推断并填写 Teambition 工时。当用户说「填工时」「登记工时」「填今天的工时」时使用本 skill。"
description_zh: "AI 辅助 Teambition 工时填写:Git 提交 → 任务匹配 → 自动填工时(支持工时查重、修改、删除、汇总;查看进行中任务、项目活跃动态)"
version: 0.5.0
---
# Teambition 工时自动填写 Skill
## 何时使用
用户说「填工时」「登记工时」「填今天的工时」「补工时」「修改工时」或类似意图时使用。
## 前置条件
1. Teambition Cookie 已配置到 `~/.workbuddy/.env`:
- `TEAMBITION_SESSIONID`
- `TEAMBITION_SESSIONID_SIG`(可选)
- `TB_ACCESS_TOKEN`
2. 工时应用已在企业安装
3. 可选用户配置:
- `ORG_ID` 或 `TEAMBITION_ORG_ID`
- `USER_ID` 或 `TEAMBITION_USER_ID`
获取方式:登录 teambition.com → F12 → Application → Cookies → 复制对应值
## 重要:API 返回结构
所有工时相关 API 返回的统一结构:
```json
{
"ok": true,
"message": "操作成功",
"payload": [...]
}
```
**工时记录在 `payload` 字段中**,不是直接返回数组。批量任务查询(tasks-bulk)同理。
## 重要:任务数据字段
| 字段 | 说明 | 注意 |
|------|------|------|
| `_id` | MongoDB ObjectId | API 交互用的唯一标识 |
| `uniqueId` | 任务编号(整数) | 前端显示的 `#2429` |
| `content` | 任务标题 | **不是 `name`(name 始终为空)** |
| `isDone` | 是否完成 | boolean |
| `dueDate` | 截止日期 | ISO 8601 格式 |
| `project` | 所属项目 | 含 `name` 和 `_id` |
| `project.uniqueIdPrefix` | 项目编号前缀 | 如 `MATRIX`、`ECX` |
| `accomplished` | 实际完成时间 | ISO 8601 格式,仅已完成任务有值 |
## 工作流程(按顺序执行)
### Step 0:自动识别当前用户
从 `~/.workbuddy/.env` 或环境变量读取 `USER_ID`(未配置则使用默认值)。
### Step 1:获取当天 Git 提交记录(标准化 JSON)
```bash
SKILL_DIR="/Users/ken/.workbuddy/skills/teambition-worklog"
# 输出结构化 JSON(推荐)
bash "$SKILL_DIR/scripts/analyze-git-commits.sh" --json /path/to/repo 2026-04-17
# 兼容文本输出
bash "$SKILL_DIR/scripts/analyze-git-commits.sh" /path/to/repo 2026-04-17
```
JSON 字段包括:`commit_count`、`commits[]`、`directories[]`,可直接作为 AI 匹配输入。
### Step 2:拉取 Teambition 任务候选(支持分页 + 批量详情)
```bash
SKILL_DIR="/Users/ken/.workbuddy/skills/teambition-worklog"
# 项目列表(分页)
bash "$SKILL_DIR/scripts/teambition-api.sh" projects [page_token] [page_size]
# 任务列表(分页)
bash "$SKILL_DIR/scripts/teambition-api.sh" tasks <project_id> [page_token] [page_size]
# 按任务编号搜索(支持逗号分隔多个)
bash "$SKILL_DIR/scripts/teambition-api.sh" search-tasks <project_id> <unique_id|id1,id2,...>
# 任务详情批量查询
bash "$SKILL_DIR/scripts/teambition-api.sh" tasks-bulk "task_id1,task_id2"
# 按项目 + 完成时间范围拉取已完成任务(自动分页遍历)
bash "$SKILL_DIR/scripts/teambition-api.sh" project-done-tasks <project_id> <start_date> <end_date> [--json] [--page-size <n>]
```
**搜索任务建议**:优先使用 `search-tasks` 按编号搜索,比遍历全量任务快得多。
**project-done-tasks 使用场景**:
- 生成发版日志 / 迭代总结
- 统计某段时间内团队完成的任务量
- 按完成日期筛选(基于 `accomplished` 字段)
- 返回字段:`id`, `uniqueId`, `content`, `accomplished`, `executor`, `creator`, `project`, `dueDate`
### Step 2.5:我的任务快捷列表(跨项目查询)
通过 `/my/api/tasks/query` 端点,使用 TQL 查询跨项目的任务快捷视图:
```bash
SKILL_DIR="/Users/ken/.workbuddy/skills/teambition-worklog"
# 我创建的任务(默认只返回未完成)
bash "$SKILL_DIR/scripts/teambition-api.sh" my-tasks created
# 我指派给他人的任务
bash "$SKILL_DIR/scripts/teambition-api.sh" my-tasks assigned
# 我参与的任务
bash "$SKILL_DIR/scripts/teambition-api.sh" my-tasks involved
# 选项
bash "$SKILL_DIR/scripts/teambition-api.sh" my-tasks created --all # 包含已完成
bash "$SKILL_DIR/scripts/teambition-api.sh" my-tasks created --json # 原始 JSON 输出
bash "$SKILL_DIR/scripts/teambition-api.sh" my-tasks created --json 20 # 指定每页数量
```
**my-tasks 返回结构**(不同于工时 API):
```json
{
"code": 200,
"data": {
"totalSize": 215,
"nextPageToken": "...",
"result": [
{
"id": "task_id",
"content": "任务标题",
"uniqueId": 2433,
"isDone": false,
"projectId": "project_id",
"projectInfo": {"name": "矩阵", "uniqueIdPrefix": "MATRIX"},
"executorUserInfo": {"name": "执行人"},
"priority": 0,
"dueDate": "2026-05-11T10:00:00Z"
}
]
}
}
```
**使用场景**:快速定位用户相关的任务,获取 task_id 后可直接用于工时填写。
### Step 2.6:查看活跃任务(项目动态 / 进行中任务)
查看今日或近期有更新的任务,帮助跟踪进度:
```bash
SKILL_DIR="/Users/ken/.workbuddy/skills/teambition-worklog"
# 查看我创建的进行中任务(跨项目,默认只返回未完成)
bash "$SKILL_DIR/scripts/teambition-api.sh" my-tasks created --json
# 查看矩阵项目今日活跃任务(按 updated 字段过滤)
# 需要先拉取任务列表,再按日期筛选(见下方 Python 脚本)
# 查看矩阵项目所有任务(分页,支持 nextPageToken 翻页)
bash "$SKILL_DIR/scripts/teambition-api.sh" tasks <project_id> [page_token] [page_size]
```
**Python 筛选今日活跃任务的示例脚本**:
```python
import json, sys
from datetime import datetime
data = json.load(sys.stdin)
tasks = data.get('result', []) # 注意:tasks API 返回结构是 {'result': [...]}, 不是 {'data':{'result':[...]}}
today = '2026-05-06' # 可改为具体日期如 '2026-05-01'
updated_today = [t for t in tasks if t.get('updated', '')[:10] == today]
recent = [t for t in tasks if t.get('updated', '')[:10] >= '2026-05-01']
for t in sorted(updated_today, key=lambda x: x.get('updated', ''), reverse=True):
uid = t.get('uniqueId', 'N/A')
content = t.get('content', '')[:60]
is_done = t.get('isDone', False)
due = t.get('dueDate', '')[:10] if t.get('dueDate') else '-'
exec_n = t.get('executor', {}).get('name', '-') if t.get('executor') else '-'
upd = t.get('updated', '')[11:16]
stage = t.get('stage', {}).get('name', '-') if t.get('stage') else '-'
status = '[完成]' if is_done else '[进行中]'
print(f'#{uid} {status} | {upd} | 截止:{due} | 执行:{exec_n} | 阶段:{stage}')
print(f' {content}')
```
**注意**:
- `tasks` API 返回结构为 `{"result": [...], "nextPageToken": "...", "totalSize": N}`,**不是** `{"data": {"result": [...]}}`
- 分页需将 `nextPageToken` 作为第二个参数传入脚本
- `updated` 字段为 ISO 8601 格式(例:`2026-05-06T14:34:00.000Z`),取前 10 位即为日期
- 需要遍历全量任务才能找到某日更新的条目(无服务端按 updated 过滤的 API)
**常用项目 ID**(见 MEMORY.md):
| 项目名 | Project ID |
|--------|-----------|
| 矩阵 | `607e7dcda0d8c08864d129f6` |
| ECShopX4.0 | `619b81caccc9d1bf69e6bb0e` |
| DigiOS-OMS | `60b71b5d92c96b6938f8636e` |
| 标准产品-OMS SaaS | `607e786ff477e28a891d33f5` |
### Step 3:AI 语义匹配并生成工时建议
输入:
- Git 结构化提交(Step 1)
- Teambition 任务候选(Step 2)
输出建议格式:
```text
任务名 | 工时 | 依据
```
### Step 4:写入前查重(按日期查询已填工时)
```bash
# 默认查询今天
bash "$SKILL_DIR/scripts/teambition-api.sh" list-worktime
# 指定日期/区间
bash "$SKILL_DIR/scripts/teambition-api.sh" list-worktime 2026-04-17 2026-04-17
```
通过返回 `payload` 中 `_objectId`(任务ID)+ `date` 判断是否重复写入。
### Step 5:新增 / 修改 / 删除工时
```bash
# 新增
bash "$SKILL_DIR/scripts/teambition-api.sh" add-worktime <task_id> <hours> [date] [note]
# 查询单条工时
bash "$SKILL_DIR/scripts/teambition-api.sh" worktime-item <worktime_id>
# 修改(参数 '-' 表示沿用原值)
bash "$SKILL_DIR/scripts/teambition-api.sh" update-worktime <worktime_id> [hours|-] [date|-] [note|-]
# 删除
bash "$SKILL_DIR/scripts/teambition-api.sh" delete-worktime <worktime_id>
# 批量新增
bash "$SKILL_DIR/scripts/teambition-api.sh" batch-worktime worklog.json
```
### Step 6:查看工时汇总
```bash
# 查看今天的工时汇总(自动关联任务名和项目名)
bash "$SKILL_DIR/scripts/teambition-api.sh" worktime-summary
# 指定日期范围
bash "$SKILL_DIR/scripts/teambition-api.sh" worktime-summary 2026-04-01 2026-04-30
```
返回 JSON 包含 `total_hours`、`record_count`、`records[]`(每条含 uid、project、content、hours、desc)。
## API 端点参考
| 功能 | 端点 |
|------|------|
| 项目列表(分页) | `GET /api/v3/projects?_organizationId={orgId}&pageSize=&pageToken=` |
| 任务列表(分页) | `GET /api/v2/projects/{id}/tasks?...&pageSize=&pageToken=` |
| 我的任务快捷列表 | `POST /my/api/tasks/query`(需 `x-tenant-id` 头) |
| 任务详情批量 | `POST /api/tasks/bulk` |
| 按日期查询工时 | `POST /api/work-time/list/dates-users` |
| 工时详情 | `GET /api/work-time/{worktimeId}` |
| 新增工时 | `POST /api/work-time/batch` |
| 修改工时 | `PUT /api/work-time/{worktimeId}` |
| 删除工时 | `DELETE /api/work-time/{worktimeId}` |
| 任务工时概览 | `GET apps.teambition.com/work-time-server/variables/worktime` |
| 按完成时间筛选任务 | `GET /api/v2/projects/{id}/tasks?filter=...`(本地遍历 + `accomplished` 过滤) |
## 环境变量注意事项
- 脚本通过 `export` 导出变量,Python 子进程可以正确读取
- 但从外部 Python subprocess 调用时,需要确保环境变量已传递:
```python
# 方法1:source .env 后运行
env = dict(os.environ)
# 方法2:显式 export
```
## 错误处理
- Cookie 无效或过期:提示用户重新复制 Cookie
- 任务 ID 不存在:提示用户更换任务或跳过
- 网络请求失败:curl 有 30 秒超时,非 2xx 状态码输出警告
- 无当天 Git 提交:提示用户可手动填写或改查指定日期
## 依赖工具
- `bash`(脚本执行)
- `git`(提交记录)
- `curl`(Teambition API 调用,超时 30s)
- `python3`(JSON 处理)
don't have the plugin yet? install it then click "run inline in claude" again.