dsh-task-ledger 0.0.128 → 0.0.129
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 +524 -274
- package/dist/client.js.map +1 -1
- package/dist/host/repositories/history.repository.js +5 -0
- package/dist/host/repositories/task.repository.d.ts +8 -5
- package/dist/host/repositories/task.repository.js +15 -3
- package/dist/host/routes.js +30 -6
- package/dist/host/services/task.service.d.ts +4 -1
- package/dist/host/services/task.service.js +3 -1
- package/dist/host/types.d.ts +4 -0
- package/package.json +2 -2
- package/skill/README.md +3 -3
- package/skill/SKILL.md +21 -4
- package/skill/package.json +1 -1
- package/skill/references/state-model.md +3 -3
- 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,9 @@ import { failureOf, runLedgerScript } from "./runner.js";
|
|
|
5
5
|
function toRecord(raw, workspace) {
|
|
6
6
|
const src = typeof raw.src === "string" ? raw.src : "";
|
|
7
7
|
const line = typeof raw.line === "number" ? raw.line : 0;
|
|
8
|
+
// history --json 的 src 相对 repo 根(ledger/history/YYYYMM.md),
|
|
9
|
+
// skill 的 delete --src 只收相对 ledger/ 的路径(history/YYYYMM.md)⇒ 在这里收口一次。
|
|
10
|
+
const deleteSrc = src.startsWith("ledger/") ? src.slice("ledger/".length) : src;
|
|
8
11
|
const text = (value) => typeof value === "string" ? value : "";
|
|
9
12
|
return {
|
|
10
13
|
// ⚠️ 必须带工作区:各仓的 src 都是 `ledger/history/YYYYMM.md`、line 各自编号,
|
|
@@ -30,6 +33,8 @@ function toRecord(raw, workspace) {
|
|
|
30
33
|
filePath: text(raw.worklog) === ""
|
|
31
34
|
? ""
|
|
32
35
|
: path.join(workspace.path, "ledger", "history", text(raw.worklog)),
|
|
36
|
+
src: deleteSrc,
|
|
37
|
+
line,
|
|
33
38
|
};
|
|
34
39
|
}
|
|
35
40
|
export async function readHistory(workspace, options) {
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
/** 界面行内按钮对应的动作:认领 / 释放 / 取消归档 /
|
|
2
|
-
export type TaskAction = "claim" | "release" | "cancel" | "close";
|
|
1
|
+
/** 界面行内按钮对应的动作:认领 / 释放 / 取消归档 / 正常结案 / 删除。 */
|
|
2
|
+
export type TaskAction = "claim" | "release" | "cancel" | "close" | "delete";
|
|
3
3
|
/** 写命令的阶段 key(与 skill `runner.go` 里的 `stepf(...)` 一一对应)。 */
|
|
4
4
|
export type TaskActionStep = "check" | "sync" | "write" | "commit" | "push";
|
|
5
5
|
/**
|
|
6
6
|
* 跑一条任务写命令。
|
|
7
7
|
*
|
|
8
|
-
* @param summary -
|
|
9
|
-
* 留空就不传 `--summary`(skill 允许取消不带摘要;正常结案由界面强制填)。
|
|
8
|
+
* @param summary - 取消 / 结案的摘要、删除的留言;留空就不传 `--summary`。
|
|
10
9
|
* @param onStep - 过程步骤回调(逐条转发给界面做进度翻牌),不传就不让 skill 打标记。
|
|
10
|
+
* @param history - 给就是删历史行(`delete --src/--line`),不给就是删在办任务(`delete --id`)。
|
|
11
11
|
*/
|
|
12
|
-
export declare function runTaskAction(repo: string, id: string, action: TaskAction, summary?: string, onStep?: (step: TaskActionStep) => void
|
|
12
|
+
export declare function runTaskAction(repo: string, id: string, action: TaskAction, summary?: string, onStep?: (step: TaskActionStep) => void, history?: {
|
|
13
|
+
readonly src: string;
|
|
14
|
+
readonly line: number;
|
|
15
|
+
}): Promise<void>;
|
|
@@ -12,15 +12,16 @@ const ACTION_NAME = {
|
|
|
12
12
|
release: "释放",
|
|
13
13
|
cancel: "取消",
|
|
14
14
|
close: "结案",
|
|
15
|
+
delete: "删除",
|
|
15
16
|
};
|
|
16
17
|
/**
|
|
17
18
|
* 跑一条任务写命令。
|
|
18
19
|
*
|
|
19
|
-
* @param summary -
|
|
20
|
-
* 留空就不传 `--summary`(skill 允许取消不带摘要;正常结案由界面强制填)。
|
|
20
|
+
* @param summary - 取消 / 结案的摘要、删除的留言;留空就不传 `--summary`。
|
|
21
21
|
* @param onStep - 过程步骤回调(逐条转发给界面做进度翻牌),不传就不让 skill 打标记。
|
|
22
|
+
* @param history - 给就是删历史行(`delete --src/--line`),不给就是删在办任务(`delete --id`)。
|
|
22
23
|
*/
|
|
23
|
-
export async function runTaskAction(repo, id, action, summary = "", onStep) {
|
|
24
|
+
export async function runTaskAction(repo, id, action, summary = "", onStep, history) {
|
|
24
25
|
const opts = {
|
|
25
26
|
timeoutMs: WRITE_TIMEOUT_MS,
|
|
26
27
|
...(onStep === undefined
|
|
@@ -57,6 +58,17 @@ export async function runTaskAction(repo, id, action, summary = "", onStep) {
|
|
|
57
58
|
repo,
|
|
58
59
|
], opts);
|
|
59
60
|
break;
|
|
61
|
+
case "delete":
|
|
62
|
+
// 留言可选;删除时刻由 skill 外壳统一算,插件不补录。
|
|
63
|
+
result = await runLedgerCommand("delete", [
|
|
64
|
+
...(history === undefined
|
|
65
|
+
? ["--id", id]
|
|
66
|
+
: ["--src", history.src, "--line", String(history.line)]),
|
|
67
|
+
...(summary === "" ? [] : ["--summary", summary]),
|
|
68
|
+
"--repo",
|
|
69
|
+
repo,
|
|
70
|
+
], opts);
|
|
71
|
+
break;
|
|
60
72
|
}
|
|
61
73
|
if (!result.ok)
|
|
62
74
|
throw failureOf(result, `${ACTION_NAME[action]}失败:`);
|
package/dist/host/routes.js
CHANGED
|
@@ -271,21 +271,45 @@ export function registerRoutes(webServer, deps) {
|
|
|
271
271
|
if (action !== "claim" &&
|
|
272
272
|
action !== "release" &&
|
|
273
273
|
action !== "cancel" &&
|
|
274
|
-
action !== "close"
|
|
275
|
-
|
|
276
|
-
|
|
274
|
+
action !== "close" &&
|
|
275
|
+
action !== "delete")
|
|
276
|
+
throw new Error(`${BAD_REQUEST}action 只能是 claim / release / cancel / close / delete`);
|
|
277
|
+
// 摘要 / 留言:一句话就够,超长的截掉(历史行不该被一段小作文撑开)
|
|
277
278
|
const summary = typeof body.summary === "string" ? body.summary.trim().slice(0, 200) : "";
|
|
278
|
-
//
|
|
279
|
+
// 正常结案必须有摘要(取消 / 删除可以没有):空着也要在界面先挡住,这里兜一层
|
|
279
280
|
if (action === "close" && summary === "")
|
|
280
281
|
throw new Error(`${BAD_REQUEST}结案必须填一句摘要`);
|
|
281
282
|
const id = typeof body.id === "string" ? body.id.trim() : "";
|
|
282
|
-
|
|
283
|
+
// 删历史行不用任务号,改用 skill 的 delete --src/--line 定位(src 相对 ledger/)
|
|
284
|
+
const src = typeof body.src === "string" ? body.src.trim() : "";
|
|
285
|
+
const line = typeof body.line === "number" &&
|
|
286
|
+
Number.isInteger(body.line) &&
|
|
287
|
+
body.line > 0
|
|
288
|
+
? body.line
|
|
289
|
+
: 0;
|
|
290
|
+
const historyDelete = action === "delete" && src !== "";
|
|
291
|
+
if (historyDelete) {
|
|
292
|
+
if (!src.startsWith("history/") ||
|
|
293
|
+
!src.endsWith(".md") ||
|
|
294
|
+
src.includes(".."))
|
|
295
|
+
throw new Error(`${BAD_REQUEST}历史文件路径不合法`);
|
|
296
|
+
if (line === 0)
|
|
297
|
+
throw new Error(`${BAD_REQUEST}历史行号不合法`);
|
|
298
|
+
}
|
|
299
|
+
else if (id === "") {
|
|
283
300
|
throw new Error(`${BAD_REQUEST}必须给任务号`);
|
|
301
|
+
}
|
|
284
302
|
const workspaceId = typeof body.workspace === "string" ? body.workspace : "";
|
|
285
303
|
const workspace = (await workspacesOf(deps)).find((item) => item.id === workspaceId);
|
|
286
304
|
if (workspace === undefined)
|
|
287
305
|
throw new Error(`${BAD_REQUEST}找不到这个工作区,改不了任务`);
|
|
288
|
-
input = {
|
|
306
|
+
input = {
|
|
307
|
+
action,
|
|
308
|
+
repo: workspace.path,
|
|
309
|
+
id,
|
|
310
|
+
summary,
|
|
311
|
+
...(historyDelete ? { src, line } : {}),
|
|
312
|
+
};
|
|
289
313
|
}
|
|
290
314
|
catch (error) {
|
|
291
315
|
sendWriteFailure(res, error);
|
|
@@ -5,7 +5,10 @@ export interface TaskActionInput {
|
|
|
5
5
|
/** 任务所在工作区根(skill 定位台账用)。 */
|
|
6
6
|
readonly repo: string;
|
|
7
7
|
readonly id: string;
|
|
8
|
-
/**
|
|
8
|
+
/** 删除历史行时的定位(相对 ledger/ 的路径 + 原文行号);不给就是删在办任务。 */
|
|
9
|
+
readonly src?: string;
|
|
10
|
+
readonly line?: number;
|
|
11
|
+
/** 取消 / 删除时的一句话留言(可选;进过程文档执行记录)。 */
|
|
9
12
|
readonly summary?: string;
|
|
10
13
|
}
|
|
11
14
|
/**
|
|
@@ -10,6 +10,8 @@ import { runTaskAction, } from "../repositories/task.repository.js";
|
|
|
10
10
|
* 命令跑完 / 失败前都会先收到前面那几个阶段,界面据此换文案。
|
|
11
11
|
*/
|
|
12
12
|
export async function actOnTask(input, onStep) {
|
|
13
|
-
await runTaskAction(input.repo, input.id, input.action, input.summary ?? "", onStep
|
|
13
|
+
await runTaskAction(input.repo, input.id, input.action, input.summary ?? "", onStep, input.src !== undefined && input.line !== undefined
|
|
14
|
+
? { src: input.src, line: input.line }
|
|
15
|
+
: undefined);
|
|
14
16
|
invalidate();
|
|
15
17
|
}
|
package/dist/host/types.d.ts
CHANGED
|
@@ -236,6 +236,10 @@ export interface HistoryRecord {
|
|
|
236
236
|
readonly finished: string;
|
|
237
237
|
/** 过程文档绝对路径;空串 = 这行没有 worklog,不可点开。 */
|
|
238
238
|
readonly filePath: string;
|
|
239
|
+
/** 历史文件相对 ledger/ 的路径(skill `delete --src` 口径);空 = 定位不到,不给删。 */
|
|
240
|
+
readonly src: string;
|
|
241
|
+
/** 原文行号(1 起);0 = 定位不到,不给删。 */
|
|
242
|
+
readonly line: number;
|
|
239
243
|
}
|
|
240
244
|
/** `/history/list` 响应:选中那个月的结案记录(按结案时间正序)。
|
|
241
245
|
* 分页不在这里做 —— 整月一次下发,前端按行号做虚拟滚动。 */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-task-ledger",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.129",
|
|
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.30.1"
|
|
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`(15 列),只由脚本写。
|
|
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` | 已结案(一行一条,15 列) |
|
|
24
24
|
|
|
25
25
|
## 为什么这么设计
|
|
26
26
|
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
**不需要安装任何东西**:直接执行上面那个路径就行。它是个 `sh` 脚本——若某个安装环节丢了可执行位(报 `Permission denied`),前面加 `sh ` 照样能跑:`sh <SKILL.md 所在目录>/scripts/progress <子命令> --repo <工作区根>`。
|
|
40
40
|
|
|
41
|
-
子命令:`new` `claim` `set` `log` `close` `list` `history` `show` `whoami` `validate`。命令参考(参数 / 一句话 / 举例)、任务生命周期、纪律(数据完整性 / 人类授权 / 故障处置)全在 `SKILL.md`;参数细节看 `<子命令> --help`(不要凭记忆编)。
|
|
41
|
+
子命令:`new` `claim` `set` `log` `close` `delete` `list` `history` `show` `whoami` `validate`。命令参考(参数 / 一句话 / 举例)、任务生命周期、纪律(数据完整性 / 人类授权 / 故障处置)全在 `SKILL.md`;参数细节看 `<子命令> --help`(不要凭记忆编)。
|
|
42
42
|
|
|
43
43
|
## 深入参考(references/,按需读)
|
|
44
44
|
|
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
|
---
|
|
@@ -22,7 +22,7 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
22
22
|
|
|
23
23
|
## 命令参考
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
十五个子命令:`init`(初始化本机身份,一台机器一次)+ 前六个写命令(`new`/`claim`/`set`/`log`/`close`/`delete`)+ 后八个只读命令(`list` / `stats` / `owners` / `show` / `history` / `root` / `whoami` / `validate`);何时用哪个见「任务生命周期」。参数语法看 `<子命令> --help`;下表说每个参数干什么、何时用。
|
|
26
26
|
|
|
27
27
|
只读命令里只有 `root` 特殊:**它在定位仓库之前跑**(「这个目录有没有台账」不能要求先有台账),不认 `--repo`、不读台账内容,只按结构判定。其余七个都先定位工作区根(带 `--repo` 或往上找)。
|
|
28
28
|
|
|
@@ -126,6 +126,21 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
126
126
|
- 正常结案:`close --id <任务号> --summary "发布流程走通,验证 25 项全过"`
|
|
127
127
|
- 取消(用户明确说「取消 / 作废」):「这个任务作废掉」→ `close --id <任务号> --cancel --summary "需求已被「xxx」做掉"`
|
|
128
128
|
|
|
129
|
+
### delete — 删除(建错的 / 垃圾任务)
|
|
130
|
+
|
|
131
|
+
**只认一个触发词:用户原话明确说「删除」。**「删掉 / 清掉 / 清理 / 移除」都不算,**不要推测意图、也不要用反问把它们转成删除**,只回一句「要删除请明确说『删除』」;「取消 / 作废」走第 9 条,「不做了 / 先放一放」走第 5 条。
|
|
132
|
+
|
|
133
|
+
**二次确认(硬门槛,一次一条)**:即使用户明确说了「删除」,也**不许直接跑**。先复述要删的是哪一条(在办:任务号 + 标题;历史:`--src` + `--line` + 标题),再问一句「确定要删除这个东西吗?」;**只有用户明确答复确认**(「确定」「删吧」「是」)才执行 `delete`。含糊、改口、没答复、答非所问 ⇒ 不删、停下,不反复追问、不替用户脑补同意。一次确认只对这一条、这一次有效;删下一条要重新问。删了没有恢复入口,原始数据仍留在台账文件里。
|
|
134
|
+
|
|
135
|
+
| 参数 | 含义 |
|
|
136
|
+
|---|---|
|
|
137
|
+
| `--id <任务号>` | 删除在办任务(公共池或自己名下分片):移进历史,结果列留空、删除三列落值;公共池任务不必先 `claim` |
|
|
138
|
+
| `--src <历史文件> --line <行号>` | 删除历史表格里那一行。`--src` 收相对 `ledger/` 的路径(如 `history/202610.md`),`--line` 是 `history --json` 给出的 `line`;行上原来的结果列与摘要一律不动 |
|
|
139
|
+
| `--summary <留言>` | 可省;只进过程文档执行记录,不写历史摘要 |
|
|
140
|
+
| `--repo <工作区根>` | 同上 |
|
|
141
|
+
|
|
142
|
+
`--id` 与 `--src` 二选一。删除后该行从所有列表、统计、趋势中整行消失,**没有开关、没有恢复、没有查询入口**;原始数据仍留在台账文件里。删除是数据纠错,取消仍是「这单被正式作废」的业务事实、照常计入结案统计 —— 别把两者混用。
|
|
143
|
+
|
|
129
144
|
### list — 查在办
|
|
130
145
|
|
|
131
146
|
| 参数 | 含义 |
|
|
@@ -331,7 +346,8 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
331
346
|
7. **释放**:仅当用户明确说「退回去 / 释放掉」→ `set --id <任务号> --release`。任务回公共池,别人可认领。
|
|
332
347
|
8. **正常结案(做完了)**:仅当用户明确说「把这个任务结束掉 / close 掉」→ `close --id <任务号> --summary "…"`,**不带 `--cancel`**;说得含糊(「做完了」「验收通过」)先反问「是要结束这个任务吗?」。收尾顺序:**先补完正文 + 记 log,最后才 close** —— 关了就不能再写。
|
|
333
348
|
9. **取消(作废)**:**只有**用户明确说「取消 / 作废」→ `close --id <任务号> --cancel [--summary "原因"]`。用户说「关闭 / 结案 / 结束」一律走第 8 条,**不许加 `--cancel`**;「不做了 / 先放一放 / 以后再做」是一暂停、不是取消(走第 5 条,状态不动);「需求不成立」只是理由、不是命令。含糊先问「是要**取消(作废)**还是**正常结案(做完了)**?」。公共池任务(未认领)只有这条入口 —— 想正常结案得先 `claim`。
|
|
334
|
-
10.
|
|
349
|
+
10. **删除**:**只有**用户原话明确说「删除」才进入这条;「删掉 / 清掉 / 清理 / 移除」不算(判定见「delete」节),「取消 / 作废」走第 9 条,「不做了 / 先放一放」走第 5 条。**先二次确认**:复述要删哪条 → 问「确定要删除这个东西吗?」→ 拿到用户明确答复确认,才跑在办 `delete --id <任务号> [--summary "留言"]`(公共池不必先 claim)或历史行 `delete --src <历史文件> --line <行号> [--summary "留言"]`。删了就删了,没有开关、恢复或查询入口;一次确认只对这一条这一次有效。
|
|
350
|
+
11. **查询**:在办 `list` / 单条 `show` / 已结案 `history`(默认只近 3 个自然月,更早的要 `--months` / `--since`)。
|
|
335
351
|
|
|
336
352
|
## 过程文档
|
|
337
353
|
|
|
@@ -379,7 +395,7 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
379
395
|
|
|
380
396
|
### 数据完整性(脚本管不了的,违反了数据就脏)
|
|
381
397
|
|
|
382
|
-
- **执行记录禁手改**:只由脚本按 `new / claim / set / release / log / close` 追加,只增不改(**交接记的是 `set`**,看不到 `handoff`
|
|
398
|
+
- **执行记录禁手改**:只由脚本按 `new / claim / set / release / log / close / cancel / delete` 追加,只增不改(**交接记的是 `set`**,看不到 `handoff` 是正常的;取消记 `cancel`、删除记 `delete`)。
|
|
383
399
|
- **改正文必配一条日志**:动了 worklog 的正文(改一句、补一节、改标题、修错字都算)就必须立刻跑一次 `log`。
|
|
384
400
|
- **换人只能「释放 → 认领」**:`set --release` 放回公共池,对方自己 `claim`;不许替别人挂名字。`set --owner <别人>`(预留转接通道,agent 一律不用)。
|
|
385
401
|
- **身份由脚本从本机 identity 文件自取,agent 全程不传身份**:跑命令前不用查身份;只有当命令**退出码为 100** 时,才按 `references/init-identity.md` 引导用户跑 `init`(一台机器一次)。查自己用 `--mine`,查别人才传**对方 uuid**(`list --owner <uuid>`);释放用 `--release`,不传身份。
|
|
@@ -395,6 +411,7 @@ allowed-tools: Read,Edit,Bash,Grep
|
|
|
395
411
|
| `log` | 免确认 | 本任务的推进 / 卡点 / 交付记录直接跑,跑完一句话交代「已记执行记录:…」;要替用户下结论,先问(任务不在自己名下会直接被拒) |
|
|
396
412
|
| `close`(正常结案) | 独立授权 | 仅认明确说「结束掉 / close 掉」(完整判定见生命周期第 8 条);**不带 `--cancel`**;说得含糊必须反问「是要结束这个任务吗?」;**agent 自判「干完了」不算** |
|
|
397
413
|
| `close --cancel`(取消) | 独立授权 | **只有用户明确说「取消 / 作废」才跑**(生命周期第 9 条);用户没说「取消 / 作废」一律不许加 `--cancel`;「不做了 / 先放一放」是暂停,不是取消;含糊先问「取消还是正常结案」 |
|
|
414
|
+
| `delete`(删除) | 独立授权 + **二次确认** | **只认用户原话明确说「删除」**(生命周期第 10 条 +「delete」节);「删掉 / 清掉 / 清理 / 移除」不算,**不许反问把它们转成删除**;即使说了也**必须先复述要删哪条、问「确定要删除这个东西吗?」**,拿到明确答复确认才跑;「取消 / 作废」走 `close --cancel`,「不做了 / 先放一放」是暂停;一次确认只对一条一次有效,删了没有恢复入口 |
|
|
398
415
|
| `list` / `stats` / `owners` / `show` / `history` / `root` / `whoami` / `validate` | 只读 | 直接跑 |
|
|
399
416
|
|
|
400
417
|
### 故障处置(跑之后出事怎么办)
|
package/skill/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-ledger",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.51",
|
|
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",
|
|
@@ -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 文件 15 列**:Finished / Created / Title / Category / Tags / Owner / Owner Name / Creator / Creator Name / Summary / Result / Worklog / Deleted / Deleted By / Deleted At(2026-10-29 起写英文表头);只认 15 列,列数不符的行静默跳过,不告警、不兼容、不提示迁移。末三列是删除标记 `yes` / 删除人 uuid / UTC 删除时刻,未删留空;`Deleted == "yes"` 的行从所有列表、统计、趋势中整行忽略,原始行仍留在文件里。排序与 `--since` / `--until` 按**结案时间**。(`history` 命令的人话输出只展示其中几列:结案时间、负责人、标题。)
|
|
34
34
|
- **owner / creator 两列存的是 uuid**(与任务里一致,身份只认 uuid);紧随其后的 `owner_name` / `creator_name` 两列**落盘**结案那一刻的显示名 —— 改名不回写旧行,看历史看到的就是当时那个名字。老行(升级前落的)没有名字时按名册兜底补一次展示值,**不回写文件**。
|
|
35
35
|
|
|
36
36
|
## 任务号
|
|
@@ -47,7 +47,7 @@ close → 历史层 + 封卷 + 移出自己名下
|
|
|
47
47
|
|
|
48
48
|
## 历史层
|
|
49
49
|
|
|
50
|
-
- 按**结案时间**分月存放,
|
|
50
|
+
- 按**结案时间**分月存放,15 列(列序:Owner 之后是 `Owner Name`,再是 Creator、`Creator Name`,Summary 之后是 Result,然后是 Worklog,末尾三列是 `Deleted` / `Deleted By` / `Deleted At`);`close` 写历史行时:分类用任务原值(**建任务后不可改**),标签用终值;`delete` 删在办任务时结果列留空、删除三列落值。
|
|
51
51
|
- 存量平铺历史文件只读兼容、永不重写;`history` 连同它在内、按下面的月份区间合并。
|
|
52
52
|
- **查询区间**:`history` 先由时间参数算出要读的月份文件,再逐个「存在才读、缺月跳过」,不扫磁盘。无时间参数默认最近 3 个自然月;`--months N`(近 N 月)与 `--since/--until`(结案时间闭区间)二选一;一次最多读 13 个历史文件(按月分文件,不区分连续/分散,只数总数),超出直接报错、不读任何文件。末列文档链接只按**文件名**消费(取 basename),链接里的 `../worklog/<年月>/` 前缀只为阅读器跳转服务,解析时忽略。
|
|
53
|
-
- `history --json`
|
|
53
|
+
- `history --json` 直接按文件现状解析,名字列为空就按名册补展示值,不回写;只认 15 列,脚本不写迁移 / 兼容程序,老工作区由 agent 逐个手工改为 15 列。
|
|
Binary file
|
|
Binary file
|
|
Binary file
|