dsh-task-ledger 0.0.123 → 0.0.124
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.js +129 -74
- package/dist/client.js.map +1 -1
- package/dist/host/repositories/trend.repository.d.ts +3 -0
- package/dist/host/repositories/trend.repository.js +2 -0
- package/dist/host/services/stats.service.d.ts +3 -1
- package/dist/host/services/stats.service.js +7 -3
- package/dist/host/services/trend.service.js +4 -1
- package/dist/host/types.d.ts +5 -0
- package/package.json +2 -2
- package/skill/README.md +2 -2
- package/skill/SKILL.md +51 -27
- package/skill/assets/worklog.md +20 -19
- package/skill/package.json +1 -1
- package/skill/references/state-model.md +5 -5
- package/skill/scripts/bin/ledger-darwin-arm64 +0 -0
- package/skill/scripts/bin/ledger-linux-amd64 +0 -0
- package/skill/scripts/bin/ledger-windows-amd64.exe +0 -0
|
@@ -5,6 +5,7 @@ export declare const TREND_WEEKS = 8;
|
|
|
5
5
|
export interface OwnerCounts {
|
|
6
6
|
readonly added: number;
|
|
7
7
|
readonly done: number;
|
|
8
|
+
readonly cancelled: number;
|
|
8
9
|
readonly open: number;
|
|
9
10
|
}
|
|
10
11
|
/** 一个周桶;`from` / `to` 是**本机时区**的日期(含边界)。 */
|
|
@@ -15,6 +16,8 @@ export interface TrendBucket {
|
|
|
15
16
|
readonly added: number;
|
|
16
17
|
/** 该周结案(全部人合计)。 */
|
|
17
18
|
readonly done: number;
|
|
19
|
+
/** 该周取消(全部人合计)。 */
|
|
20
|
+
readonly cancelled: number;
|
|
18
21
|
/** 该周结束时仍未结案(全部人合计,含窗口前遗留)。 */
|
|
19
22
|
readonly open: number;
|
|
20
23
|
/** uuid → 按人明细(「只看我的」用;没要 / 该人该周没数据则没有这个 key)。 */
|
|
@@ -42,6 +42,7 @@ function parseOwners(raw, where) {
|
|
|
42
42
|
out[uuid] = {
|
|
43
43
|
added: num(cell, "added", where),
|
|
44
44
|
done: num(cell, "done", where),
|
|
45
|
+
cancelled: num(cell, "cancelled", where),
|
|
45
46
|
open: num(cell, "open", where),
|
|
46
47
|
};
|
|
47
48
|
}
|
|
@@ -80,6 +81,7 @@ export function parseTrend(raw, where) {
|
|
|
80
81
|
to: day(item, "to", where),
|
|
81
82
|
added: num(item, "added", where),
|
|
82
83
|
done: num(item, "done", where),
|
|
84
|
+
cancelled: num(item, "cancelled", where),
|
|
83
85
|
open: num(item, "open", where),
|
|
84
86
|
...(owners === undefined ? {} : { owners }),
|
|
85
87
|
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { BoardHomePayload, LedgerWorkspace, StatsPayload, TrendView } from "../types.js";
|
|
2
|
-
/** 本周 /
|
|
2
|
+
/** 本周 / 上周结案总数 = 趋势最后两个桶的 done + cancelled(后者为上周)。 */
|
|
3
3
|
export interface WeekDone {
|
|
4
4
|
readonly weekDone: number | null;
|
|
5
5
|
readonly lastWeekDone: number | null;
|
|
6
|
+
readonly weekCancelled: number | null;
|
|
7
|
+
readonly lastWeekCancelled: number | null;
|
|
6
8
|
readonly weekFrom: string;
|
|
7
9
|
readonly weekTo: string;
|
|
8
10
|
readonly lastWeekFrom: string;
|
|
@@ -20,8 +20,10 @@ export function weekDoneFromTrend(trend, fallback, fallbackLast) {
|
|
|
20
20
|
const thisWeek = buckets[buckets.length - 1];
|
|
21
21
|
const lastWeek = buckets[buckets.length - 2];
|
|
22
22
|
return {
|
|
23
|
-
weekDone: thisWeek === undefined ? null : thisWeek.done,
|
|
24
|
-
lastWeekDone: lastWeek === undefined ? null : lastWeek.done,
|
|
23
|
+
weekDone: thisWeek === undefined ? null : thisWeek.done + thisWeek.cancelled,
|
|
24
|
+
lastWeekDone: lastWeek === undefined ? null : lastWeek.done + lastWeek.cancelled,
|
|
25
|
+
weekCancelled: thisWeek === undefined ? null : thisWeek.cancelled,
|
|
26
|
+
lastWeekCancelled: lastWeek === undefined ? null : lastWeek.cancelled,
|
|
25
27
|
weekFrom: thisWeek?.from ?? fallback.from,
|
|
26
28
|
weekTo: thisWeek?.to ?? fallback.to,
|
|
27
29
|
lastWeekFrom: lastWeek?.from ?? fallbackLast.from,
|
|
@@ -108,9 +110,11 @@ export async function getBoardStats(workspaces, now = new Date()) {
|
|
|
108
110
|
: max === null
|
|
109
111
|
? item.oldestOpenDays
|
|
110
112
|
: Math.max(max, item.oldestOpenDays), null),
|
|
111
|
-
//
|
|
113
|
+
// 这四个数由 getBoardHome 从趋势桶回填(趋势全挂时保持 null ⇒ 界面留 —)
|
|
112
114
|
weekDone: null,
|
|
113
115
|
lastWeekDone: null,
|
|
116
|
+
weekCancelled: null,
|
|
117
|
+
lastWeekCancelled: null,
|
|
114
118
|
weekFrom: thisWeek.from,
|
|
115
119
|
weekTo: thisWeek.to,
|
|
116
120
|
lastWeekFrom: lastWeek.from,
|
|
@@ -27,6 +27,7 @@ export function mergeTrend(rows) {
|
|
|
27
27
|
to: bucket.to,
|
|
28
28
|
added: 0,
|
|
29
29
|
done: 0,
|
|
30
|
+
cancelled: 0,
|
|
30
31
|
open: 0,
|
|
31
32
|
owners: {},
|
|
32
33
|
};
|
|
@@ -35,12 +36,14 @@ export function mergeTrend(rows) {
|
|
|
35
36
|
// 已有对象就原地累加(同一份数据只在本函数里生成,不会被外部共享)
|
|
36
37
|
current.added += bucket.added;
|
|
37
38
|
current.done += bucket.done;
|
|
39
|
+
current.cancelled += bucket.cancelled;
|
|
38
40
|
current.open += bucket.open;
|
|
39
41
|
for (const [uuid, cell] of Object.entries(bucket.owners ?? {})) {
|
|
40
|
-
const owner = current.owners[uuid] ?? { added: 0, done: 0, open: 0 };
|
|
42
|
+
const owner = current.owners[uuid] ?? { added: 0, done: 0, cancelled: 0, open: 0 };
|
|
41
43
|
current.owners[uuid] = {
|
|
42
44
|
added: owner.added + cell.added,
|
|
43
45
|
done: owner.done + cell.done,
|
|
46
|
+
cancelled: owner.cancelled + cell.cancelled,
|
|
44
47
|
open: owner.open + cell.open,
|
|
45
48
|
};
|
|
46
49
|
}
|
package/dist/host/types.d.ts
CHANGED
|
@@ -102,6 +102,9 @@ export interface BoardStatsView {
|
|
|
102
102
|
/** 本周 / 上周完成数(= 趋势最后两个桶);趋势全读不到时为 null(界面留 —)。 */
|
|
103
103
|
readonly weekDone: number | null;
|
|
104
104
|
readonly lastWeekDone: number | null;
|
|
105
|
+
/** 其中取消的数量(卡片小字「结案 X · 取消 Y」);0 时不显示小字。 */
|
|
106
|
+
readonly weekCancelled: number | null;
|
|
107
|
+
readonly lastWeekCancelled: number | null;
|
|
105
108
|
/** 两周的区间(界面悬停用,含边界)。 */
|
|
106
109
|
readonly weekFrom: string;
|
|
107
110
|
readonly weekTo: string;
|
|
@@ -118,6 +121,7 @@ export interface StatsPayload {
|
|
|
118
121
|
export interface TrendOwnerCounts {
|
|
119
122
|
readonly added: number;
|
|
120
123
|
readonly done: number;
|
|
124
|
+
readonly cancelled: number;
|
|
121
125
|
readonly open: number;
|
|
122
126
|
}
|
|
123
127
|
/** 趋势图的一根周桶(数字全由 skill `stats --trend --by-owner` 给,插件只跨工作区相加)。 */
|
|
@@ -126,6 +130,7 @@ export interface TrendBucketView {
|
|
|
126
130
|
readonly to: string;
|
|
127
131
|
readonly added: number;
|
|
128
132
|
readonly done: number;
|
|
133
|
+
readonly cancelled: number;
|
|
129
134
|
readonly open: number;
|
|
130
135
|
/** uuid → 按人明细;「只看我的」直接取自己那条,勾选零请求。 */
|
|
131
136
|
readonly owners: Readonly<Record<string, TrendOwnerCounts>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-task-ledger",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.124",
|
|
4
4
|
"description": "Task ledger board for dsh (DeepSeek Harness): read-only board over task-ledger skill workspaces. The task-ledger skill is bundled — install the plugin, get the skill globally.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek",
|
|
@@ -57,6 +57,6 @@
|
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"dsh-plugin-core": "^0.
|
|
60
|
+
"dsh-plugin-core": "^0.10.0"
|
|
61
61
|
}
|
|
62
62
|
}
|
package/skill/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
- **谁在做、做到哪**:状态只在台账 JSON —— `ledger/pool.json`(公共池)+ 每人一份 `ledger/owners/<hash>.json` 分片,索引 `ledger/owners.json`。
|
|
10
10
|
- **过程正文**:全在 `ledger/worklog/<年月>/<月日>-<时分>-<说明>-<码>.md`(六节),agent 直接编辑前五节,末节「执行记录」只由脚本写。
|
|
11
|
-
- **已结案**:一行一条在 `ledger/history/<年月>.md`(
|
|
11
|
+
- **已结案**:一行一条在 `ledger/history/<年月>.md`(12 列),只由脚本写。
|
|
12
12
|
|
|
13
13
|
状态改动与正文重写分开、全部经脚本改 —— 不另建副本、不手改状态表和历史。覆盖动作:建任务、认领、释放、结案、查在办、查历史、标签归并、体检。
|
|
14
14
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
| `ledger/owners.json` | 索引:身份 uuid → 分片文件(`name` 只做显示 / 模糊筛) |
|
|
21
21
|
| `ledger/owners/<hash>.json` | 每人一份分片:自己认领的任务 |
|
|
22
22
|
| `ledger/worklog/<年月>/*.md` | 任务正文(六节) |
|
|
23
|
-
| `ledger/history/<年月>.md` | 已结案(一行一条,
|
|
23
|
+
| `ledger/history/<年月>.md` | 已结案(一行一条,12 列) |
|
|
24
24
|
|
|
25
25
|
## 为什么这么设计
|
|
26
26
|
|
package/skill/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: task-ledger
|
|
3
|
-
description: 本地任务台账,跨会话记录在办任务的归属、进度与起止。当用户要登记一件新的事(新建任务 / 建个坑 / 这活我领了)、记录已有任务的进展(接着做 / 记一条进展 / 这轮先记下)、查看任务状态或历史(现在该做什么 / 这活谁在做 /
|
|
3
|
+
description: 本地任务台账,跨会话记录在办任务的归属、进度与起止。当用户要登记一件新的事(新建任务 / 建个坑 / 这活我领了)、记录已有任务的进展(接着做 / 记一条进展 / 这轮先记下)、查看任务状态或历史(现在该做什么 / 这活谁在做 / 上周做过什么)、给任务结案 / 取消作废 / 退回(做完了 / 验收通过 / 取消 / 作废 / 退回待认领)、整理标签或检查台账一致性时加载;只是改代码、讨论方案时不要用。
|
|
4
4
|
version: 1.3.40
|
|
5
5
|
allowed-tools: Read,Edit,Bash,Grep
|
|
6
6
|
---
|
|
@@ -93,18 +93,38 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
93
93
|
|
|
94
94
|
举例:一轮干完 → `log --id <任务号> --note "改了认领即 doing(internal/actions/claim.go:56);下一步同步文档"`。
|
|
95
95
|
|
|
96
|
-
### close — 结案
|
|
96
|
+
### close — 结案 / 取消
|
|
97
|
+
|
|
98
|
+
**结案与取消是两个动作,共用一个命令,只靠 `--cancel` 区分。**
|
|
99
|
+
|
|
100
|
+
- 用户说「关闭 / 结案 / 结束 / close」⇒ **正常结案,不许加 `--cancel`**;
|
|
101
|
+
- 只有用户明确说「**取消 / 作废**」(如「这个任务取消」「作废掉」)⇒ 才加 `--cancel`;
|
|
102
|
+
- 「不做了 / 先不做了 / 以后再做 / 先放一放 / 暂停」**不是取消** —— 那是暂停:状态不动,最多记一条 `log`(见生命周期第 5 条);
|
|
103
|
+
- 「需求不成立 / 已经被别的任务做掉」是**理由**,不是命令:它只能进 `--summary`,不能当取消的触发词;
|
|
104
|
+
- 拿不准(「这个先这样吧」)⇒ 先问「是要**取消(作废)**还是**正常结案(做完了)**?」,问清再跑。
|
|
97
105
|
|
|
98
106
|
| 参数 | 含义 |
|
|
99
107
|
|---|---|
|
|
100
108
|
| `--id <任务号>` | 结哪条(必填) |
|
|
101
|
-
| `--summary "…"` |
|
|
109
|
+
| `--summary "…"` | 结案摘要(正常结案必填);**取消时可选**,写了就落历史 `Summary` 列并带进执行记录 |
|
|
110
|
+
| `--cancel` | 取消:结果列 `cancelled`、状态行 `cancelled`、执行记录追加 `cancel` 一行。**不写原因也能取消** |
|
|
102
111
|
| `--finished` | 给漏记的旧任务补用时,补录实际结案时间(`YYYY-MM-DD[ HH:MM[:SS]]`) |
|
|
103
112
|
| `--tags` | 覆盖标签终值(写进历史行;文档头部只写标签)。**结案时最该给**:任务做完了,最清楚涉及什么;不传则沿用原标签。分类不可改,历史行用它建任务时的值 |
|
|
104
113
|
|
|
105
|
-
|
|
114
|
+
干什么:结案(或取消)并封卷过程文档、删掉来源那行。**封卷后只读**(见生命周期第 8 条)。
|
|
115
|
+
|
|
116
|
+
可用范围:
|
|
117
|
+
|
|
118
|
+
- **公共池任务**(没人认领)→ 只能 `--cancel`(想正常结案先 `claim`);
|
|
119
|
+
- **我名下的任务** → 结案、取消都行;
|
|
120
|
+
- **别人名下的任务** → 拒绝。
|
|
106
121
|
|
|
107
|
-
|
|
122
|
+
结果列只有两个值:`done`(正常结案)/ `cancelled`(取消)。历史行的 `owner` / `owner_name` 是**执行这次结案/取消的人**,原创建者仍在 `creator` / `creator_name`。
|
|
123
|
+
|
|
124
|
+
举例:
|
|
125
|
+
|
|
126
|
+
- 正常结案:`close --id <任务号> --summary "发布流程走通,验证 25 项全过"`
|
|
127
|
+
- 取消(用户明确说「取消 / 作废」):「这个任务作废掉」→ `close --id <任务号> --cancel --summary "需求已被「xxx」做掉"`
|
|
108
128
|
|
|
109
129
|
### list — 查在办
|
|
110
130
|
|
|
@@ -162,9 +182,9 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
162
182
|
| `--mine` / `--owner <uuid>[,<uuid>]` | 只看自己 / 某几个人(`--owner` 可给多个 uuid,与 `--mine` 互斥) |
|
|
163
183
|
| `--by-owner` | 每个桶额外带按人明细(默认不返回,只给总数) |
|
|
164
184
|
|
|
165
|
-
|
|
185
|
+
干什么:一次遍历返回**整段桶序列**(不按桶多次调用),每桶四个数 —— `added`(该桶内新建)、`done`(正常结案)、`cancelled`(取消作废)、`open`(该桶**结束时**仍未结案)。
|
|
166
186
|
|
|
167
|
-
口径:`added` 按 `created
|
|
187
|
+
口径:`added` 按 `created`;`done` / `cancelled` 都按 `finished`,靠历史行 `Result` 列区分(`done` 只算正常结案,取消不算完成);`open` 由「当前在办 + 今天往前倒推」得出,天然含窗口之前遗留的基线 —— 结案和取消**都**会让任务离开在办,倒推时两者都要减。按人明细里 `added` 按 `creator`、`done` / `open` 按 `owner`(待认领不算任何人)。
|
|
168
188
|
|
|
169
189
|
按人的 `open` 只算**你名下**的任务,倒推时同时减去「你在那天之后新建的」(按 owner 计,与展示用的 creator 无关)—— 否则窗口之后才建、早已结案的任务会被当成那天就在办,越靠前的桶虚高得越离谱。负责人转交过的任务按**今天**的负责人归账。
|
|
170
190
|
|
|
@@ -175,8 +195,8 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
175
195
|
"granularity": "week",
|
|
176
196
|
"coverage": { "from": "2026-09-01", "to": "2026-10-29" },
|
|
177
197
|
"buckets": [
|
|
178
|
-
{ "from": "2026-09-01", "to": "2026-09-06", "added": 3, "done": 5, "open": 12,
|
|
179
|
-
"owners": { "<uuid>": { "name": "某人", "added": 1, "done": 2, "open": 4 } } }
|
|
198
|
+
{ "from": "2026-09-01", "to": "2026-09-06", "added": 3, "done": 5, "cancelled": 1, "open": 12,
|
|
199
|
+
"owners": { "<uuid>": { "name": "某人", "added": 1, "done": 2, "cancelled": 0, "open": 4 } } }
|
|
180
200
|
],
|
|
181
201
|
"warnings": []
|
|
182
202
|
}
|
|
@@ -228,7 +248,7 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
228
248
|
|
|
229
249
|
干什么:按结案时间倒序排列,每条一行,只列结案时间、负责人、标题,其他都不在表格里;要摘要 / 分类 / 标签 / 完整时间加 `--json`。不给时间参数 = 最近 3 个自然月;最多 13 个月,超了直接报错。
|
|
230
250
|
|
|
231
|
-
要「某个时间窗内结案了多少」**别拿 `history` 数条数**(只覆盖 13 个月,且一给 `--limit`,`count` 就只是返回条数)—— 用 `stats --trend <粒度>` 的桶,`done`
|
|
251
|
+
要「某个时间窗内结案了多少」**别拿 `history` 数条数**(只覆盖 13 个月,且一给 `--limit`,`count` 就只是返回条数)—— 用 `stats --trend <粒度>` 的桶,`done + cancelled` 才是该桶结案总数(`done` 只算正常结案)。
|
|
232
252
|
|
|
233
253
|
举例:「上周做过什么」→ `history --since <上周一日期>`;「今年都结掉哪些」→ `history --months 12`(超过 13 个月要分段查)。
|
|
234
254
|
|
|
@@ -308,11 +328,12 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
308
328
|
2. **建并认领 —— 仅限明确说法**:用户明确说「新建一个任务**并开始做 / 并执行**」这类带着「现在就开始」的话 → `new --title "…" --self`。直接归自己名下、「进行中」。**除这种明确说法,其他一律按第 1 条只建** —— 别替用户决定他要开始做;拿不定,问一句。
|
|
309
329
|
3. **找已有的**:用户说「我们来做 X」→ 先 `list --mine` 找自己名下的,在做的直接接着做;没有 → `list --pool` 里找,找到先问用户:「X 还没认领,认领它吗?」→ 用户点头再 `claim`;哪儿都没有 → **不擅自建**:问「要为 X 建个任务吗?」,同意才按第 1/2 条建,不同意就只干活、不登记。
|
|
310
330
|
4. **认领**:`claim --id <任务号>` —— 认到自己名下,状态即「进行中」。
|
|
311
|
-
5. **推进**:改 worklog 前五节 → 按「过程文档」节的收工三步记 `log`。卡住也 `log
|
|
331
|
+
5. **推进**:改 worklog 前五节 → 按「过程文档」节的收工三步记 `log`。卡住也 `log`(写清卡在哪,状态不动);「先放一放 / 现在不做了,一会儿做」同理 —— 是暂停,不是释放,更不是取消(取消只有用户明确说「取消 / 作废」才算)。
|
|
312
332
|
6. **交付待验收**:任务留「进行中」,「待办」写「待用户验收」,「下一步」写清验收看什么;照收工三步记一条 `log --note "已交付待验收:…"`。
|
|
313
333
|
7. **释放**:仅当用户明确说「退回去 / 释放掉」→ `set --id <任务号> --release`。任务回公共池,别人可认领。
|
|
314
|
-
8.
|
|
315
|
-
9.
|
|
334
|
+
8. **正常结案(做完了)**:仅当用户明确说「把这个任务结束掉 / close 掉」→ `close --id <任务号> --summary "…"`,**不带 `--cancel`**;说得含糊(「做完了」「验收通过」)先反问「是要结束这个任务吗?」。收尾顺序:**先补完正文 + 记 log,最后才 close** —— 关了就不能再写。
|
|
335
|
+
9. **取消(作废)**:**只有**用户明确说「取消 / 作废」→ `close --id <任务号> --cancel [--summary "原因"]`。用户说「关闭 / 结案 / 结束」一律走第 8 条,**不许加 `--cancel`**;「不做了 / 先放一放 / 以后再做」是一暂停、不是取消(走第 5 条,状态不动);「需求不成立」只是理由、不是命令。含糊先问「是要**取消(作废)**还是**正常结案(做完了)**?」。公共池任务(未认领)只有这条入口 —— 想正常结案得先 `claim`。
|
|
336
|
+
10. **查询**:在办 `list` / 单条 `show` / 已结案 `history`(默认只近 3 个自然月,更早的要 `--months` / `--since`)。
|
|
316
337
|
|
|
317
338
|
## 过程文档
|
|
318
339
|
|
|
@@ -320,27 +341,29 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
320
341
|
|
|
321
342
|
| 节 | 写什么 |
|
|
322
343
|
|---|---|
|
|
323
|
-
|
|
|
324
|
-
|
|
|
325
|
-
|
|
|
326
|
-
|
|
|
327
|
-
|
|
|
328
|
-
|
|
|
344
|
+
| Background(背景) | 为什么做:触发它的原话 / 现象 / 链接 |
|
|
345
|
+
| To Do(待办) | 还没做的、没验证的、等别人给东西的 |
|
|
346
|
+
| Next(下一步) | 下一个**具体动作**(文件:行号 级别),不写「继续推进」 |
|
|
347
|
+
| Process(过程) | 踩坑与证据:带 revision + `文件:行号` 或符号名 |
|
|
348
|
+
| Conclusion(结论) | 做成了什么、留了什么坑;只写可验证事实,评价等用户验收 |
|
|
349
|
+
| Execution Log(执行记录) | 脚本维护,**禁止手写**(见「手写边界」) |
|
|
350
|
+
|
|
351
|
+
节名**写英文**(2026-10-29 起;旧中文节名不再兼容,将统一迁移)。
|
|
329
352
|
|
|
330
353
|
规则:
|
|
331
354
|
|
|
332
|
-
-
|
|
355
|
+
- `## Execution Log` 节名一个字都别动;老文档缺这一节也不用补(脚本补的时候补的是英文那节)。
|
|
333
356
|
- 过程文档找不到时 `log` 只提示不失败;用 `show` 查路径,不要手写。
|
|
334
|
-
- 头部是四行,由脚本维护、**都不要手改**,顺序固定
|
|
357
|
+
- 头部是四行,由脚本维护、**都不要手改**,顺序固定 `Tags → Status → Created → Sealed`,值一律 `· ` 分隔:
|
|
335
358
|
|
|
336
359
|
```markdown
|
|
337
|
-
-
|
|
338
|
-
-
|
|
339
|
-
-
|
|
340
|
-
-
|
|
360
|
+
- **Tags**: 建设, DSH, 台账
|
|
361
|
+
- **Status**: doing · 2026-10-27 09:12:33 · @某人 · 8d557c6d-…
|
|
362
|
+
- **Created**: 2026-10-26 23:38:02 · @某人 · 8d557c6d-…
|
|
363
|
+
- **Sealed**: 2026-10-27 09:20:10 · @某人 · 8d557c6d-…
|
|
341
364
|
```
|
|
342
365
|
|
|
343
|
-
|
|
366
|
+
标签行与封卷行不一定有(没给标签、没结案就没有)。旧中文头部(`- **标签**:…` / 「**分类**」段)是旧格式,不再兼容,将统一迁移;`show --json` 不再标 `legacy`。
|
|
344
367
|
- 执行记录行格式 `- 时间(UTC) · 类型 · @谁 · 说明`,`@谁` 是这次动手的人、不是任务现归属;只追加、不改旧行。行首「类型」是脚本内部动作名(会见到 `release`,它就是 `set --release`);认不出就别当成新命令,按 `--help` 查。
|
|
345
368
|
- 只改某条任务的正文:`show --id <任务号>` 拿路径直接改,不另建 md;已结案的用 `history --months 12 --json` 找回链接(**人话输出里没有链接,必须加 `--json`**)——默认只查近 3 个月,结案久了的要显式放大窗口;只读不改。
|
|
346
369
|
|
|
@@ -370,7 +393,8 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
370
393
|
|---|---|---|
|
|
371
394
|
| `new` / `claim` / `set` | 动手类 | 执行前复述完整参数并取得确认;**`new` 仅当用户原话点名要建且标题可直取原话时免复述**,标题需另拟或拿不准仍复述一次(`claim`/`set` 一律复述) |
|
|
372
395
|
| `log` | 免确认 | 本任务的推进 / 卡点 / 交付记录直接跑,跑完一句话交代「已记执行记录:…」;要替用户下结论,先问(任务不在自己名下会直接被拒) |
|
|
373
|
-
| `close
|
|
396
|
+
| `close`(正常结案) | 独立授权 | 仅认明确说「结束掉 / close 掉」(完整判定见生命周期第 8 条);**不带 `--cancel`**;说得含糊必须反问「是要结束这个任务吗?」;**agent 自判「干完了」不算** |
|
|
397
|
+
| `close --cancel`(取消) | 独立授权 | **只有用户明确说「取消 / 作废」才跑**(生命周期第 9 条);用户没说「取消 / 作废」一律不许加 `--cancel`;「不做了 / 先放一放」是暂停,不是取消;含糊先问「取消还是正常结案」 |
|
|
374
398
|
| `list` / `stats` / `owners` / `show` / `history` / `root` / `whoami` / `validate` | 只读 | 直接跑 |
|
|
375
399
|
|
|
376
400
|
### 故障处置(跑之后出事怎么办)
|
package/skill/assets/worklog.md
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
# <id
|
|
1
|
+
# <id>: <title>
|
|
2
2
|
|
|
3
|
-
-
|
|
4
|
-
-
|
|
3
|
+
- **Status**: <status>
|
|
4
|
+
- **Created**: <created> · @<creator>
|
|
5
5
|
|
|
6
|
-
<!--
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
<!-- Header lines are maintained by the script, fixed order: Tags → Status → Created → Sealed.
|
|
7
|
+
The `- **Tags**: …` line is inserted at the top by new --tags; omitted when there are no tags
|
|
8
|
+
(category goes to the ledger and history only, never into this document).
|
|
9
|
+
The `- **Sealed**: …` line is appended on close. -->
|
|
9
10
|
|
|
10
|
-
##
|
|
11
|
+
## Background
|
|
11
12
|
|
|
12
|
-
<!--
|
|
13
|
+
<!-- What this is for: the words that triggered it / the symptom / a link -->
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## To Do
|
|
15
16
|
|
|
16
|
-
<!--
|
|
17
|
+
<!-- Not done yet, not verified, waiting on somebody -->
|
|
17
18
|
|
|
18
|
-
##
|
|
19
|
+
## Next
|
|
19
20
|
|
|
20
|
-
<!--
|
|
21
|
+
<!-- The next concrete action (file:line level), never "keep going" -->
|
|
21
22
|
|
|
22
|
-
##
|
|
23
|
+
## Process
|
|
23
24
|
|
|
24
|
-
<!--
|
|
25
|
+
<!-- Pitfalls and evidence: with revision + file:line or symbol names -->
|
|
25
26
|
|
|
26
|
-
##
|
|
27
|
+
## Conclusion
|
|
27
28
|
|
|
28
|
-
<!--
|
|
29
|
+
<!-- What got done, what got left behind -->
|
|
29
30
|
|
|
30
|
-
##
|
|
31
|
+
## Execution Log
|
|
31
32
|
|
|
32
|
-
<!--
|
|
33
|
-
|
|
33
|
+
<!-- Maintained by the script: appended by new / claim / set / release / log / close. Do not edit.
|
|
34
|
+
Backfill with: progress log --id <id> --note "...". -->
|
package/skill/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-ledger",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.46",
|
|
4
4
|
"description": "Task-ledger skill for coding agents: per-workspace progress tracking (ledger/pool.json + owners/<hash>.json shards + owners.json index, history, worklog) driven by a CLI script. Standalone install for CodeBuddy and other agents; also bundled inside the dsh-task-ledger DSH plugin.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"skill",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 状态与时间模型
|
|
2
2
|
|
|
3
|
-
> TL;DR:状态只有 `open` / `doing`;`done`
|
|
3
|
+
> TL;DR:状态只有 `open` / `doing`;`done`(正常结案)/ `cancelled`(取消,`close --cancel`)由 `close` 产生。认领即 `doing`(`claim` / `new --self` 都直接置)。`started` = 首次认领时间,释放不清、重新认领不刷新。`updated` 由 `new/claim/set/log` 刷新。身份由脚本自取,agent 不传 owner。
|
|
4
4
|
|
|
5
5
|
## 状态机
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ close → 历史层 + 封卷 + 移出自己名下
|
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
- **`started` 是外卖计时器**:首次认领盖上之后,释放(`set --release`)不清、重新认领不刷新 —— 逾期时钟从首次认领一口气跑到结案,转手不重置。防的是「眼看要超时,释放掉再认领回来洗时钟」;全链路没有重置 `started` 的命令(`claim` 的 `or now()` 只在它为空时才盖值;`set` 原样保留)。接手一个已超时的任务,一接单即逾期:单子已经迟了,谁端着谁负责;责任归属看执行记录流水(谁认领 / 谁释放逐笔有记录),计时器只回答「这单迟没迟」。
|
|
17
|
-
- 状态只有 `open` / `doing` 两种在办值;`done` 由 `close`
|
|
17
|
+
- 状态只有 `open` / `doing` 两种在办值;`done` / `cancelled` 由 `close` 产生(任务从池或分片消失,只留在历史里;`cancelled` 是 `close --cancel`)。**没有 `blocked`**,也没有改状态的命令。
|
|
18
18
|
- 认领 / 释放 / 交接一律先写目标、再删原处,崩在中间会同一任务号短暂出现在两处 —— 重跑一次同一条命令即幂等收敛(`already_done`),或按 `validate` 的提示删掉多余那份。
|
|
19
19
|
|
|
20
20
|
## 时间
|
|
@@ -30,7 +30,7 @@ close → 历史层 + 封卷 + 移出自己名下
|
|
|
30
30
|
- 进门:`--since` / `--until` / `--created` / `--finished` 按本机墙钟给,脚本内部转 UTC 再比较 / 落盘;除这四个参数没有任何地方要调用方传时间。
|
|
31
31
|
- **过程文档正文不动**:`show --json` 的 `worklog.text` 是原文,里面的时间是当时写进去的 UTC。
|
|
32
32
|
- 存量老数据写的是写入者本地时间、无标记,无法与 UTC 区分(JSON 是 2026-10-22 前,执行记录行是 2026-10-27 前)。
|
|
33
|
-
- **history 文件
|
|
33
|
+
- **history 文件 12 列**:Finished / Created / Title / Category / Tags / Owner / Owner Name / Creator / Creator Name / Summary / Result / Worklog(2026-10-29 起写英文表头;11 列旧文件不再兼容:读时跳过该行并告警,结案往里追加会直接报错要求先迁移);排序与 `--since` / `--until` 按**结案时间**。(`history` 命令的人话输出只展示其中几列:结案时间、负责人、标题。)
|
|
34
34
|
- **owner / creator 两列存的是 uuid**(与任务里一致,身份只认 uuid);紧随其后的 `owner_name` / `creator_name` 两列**落盘**结案那一刻的显示名 —— 改名不回写旧行,看历史看到的就是当时那个名字。老行(升级前落的)没有名字时按名册兜底补一次展示值,**不回写文件**。
|
|
35
35
|
|
|
36
36
|
## 任务号
|
|
@@ -43,11 +43,11 @@ close → 历史层 + 封卷 + 移出自己名下
|
|
|
43
43
|
- 没有 `identity.json`(未初始化)**直接报错**,提示先跑 `init`(一台机器一次);不再有兜底身份,也不读 git / 环境变量。
|
|
44
44
|
- 全站只认 UUID 这一个身份键;`list --owner` / `history --owner` **只收 uuid**(形态不是 UUID 直接报错,不静默返回空),没有 `me` 缩写,「自己」用 `--mine`。
|
|
45
45
|
- **名字不进任何判定**:按人模糊找只能走 `--owner-name <片段>`(对名册里的 `name` 做子串、不分大小写匹配,换成 uuid 集合再筛),它只是查询便利,认领 / 释放 / 交接 / 「我的」一律只比 uuid。任务上的 `owner_name` 是冗余显示字段,改名不影响归属。
|
|
46
|
-
- `close`
|
|
46
|
+
- `log` 只对自己名下的任务生效;`close` 对自己名下的做结案/取消,对公共池任务只能 `--cancel`(`close --cancel`),别人名下的拒绝;`set --release` 对已在公共池里的任务是幂等空转(退 0);`set --owner <自己>` 会把公共池里的任务认领到自己名下。
|
|
47
47
|
|
|
48
48
|
## 历史层
|
|
49
49
|
|
|
50
|
-
- 按**结案时间**分月存放,
|
|
50
|
+
- 按**结案时间**分月存放,12 列(列序:Owner 之后是 `Owner Name`,再是 Creator、`Creator Name`,Summary 之后是 Result,末列 Worklog);`close` 写历史行时:分类用任务原值(**建任务后不可改**),标签用终值。
|
|
51
51
|
- 存量平铺历史文件只读兼容、永不重写;`history` 连同它在内、按下面的月份区间合并。
|
|
52
52
|
- **查询区间**:`history` 先由时间参数算出要读的月份文件,再逐个「存在才读、缺月跳过」,不扫磁盘。无时间参数默认最近 3 个自然月;`--months N`(近 N 月)与 `--since/--until`(结案时间闭区间)二选一;一次最多读 13 个历史文件(按月分文件,不区分连续/分散,只数总数),超出直接报错、不读任何文件。末列文档链接只按**文件名**消费(取 basename),链接里的 `../worklog/<年月>/` 前缀只为阅读器跳转服务,解析时忽略。
|
|
53
53
|
- `history --json` 直接按文件现状解析,旧行没有的列不编造(名字列为空就按名册补展示值,不回写);存量九列的历史文件按 `docs/history-creator-upgrade.md` 一次性升级,脚本不认旧列数。
|
|
Binary file
|
|
Binary file
|
|
Binary file
|