dsh-task-ledger 0.0.78 → 0.0.80
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 +29 -14
- package/dist/client.js.map +1 -1
- package/dist/host/board.d.ts +2 -2
- package/dist/host/board.js +2 -2
- package/dist/host/repositories/cache.js +18 -2
- package/dist/host/repositories/identity.repository.d.ts +3 -8
- package/dist/host/repositories/identity.repository.js +32 -23
- package/dist/host/repositories/ledger.repository.d.ts +7 -3
- package/dist/host/repositories/ledger.repository.js +23 -14
- package/dist/host/repositories/records.js +20 -1
- package/dist/host/repositories/runner.d.ts +2 -2
- package/dist/host/repositories/runner.js +1 -1
- package/dist/host/routes.js +40 -11
- package/dist/host/services/home.service.d.ts +2 -2
- package/dist/host/services/home.service.js +7 -4
- package/dist/host/services/ledger-write.service.d.ts +4 -4
- package/dist/host/services/ledger-write.service.js +7 -7
- package/dist/host/services/trend.service.d.ts +2 -2
- package/dist/host/services/trend.service.js +9 -10
- package/dist/host/services/uuid.d.ts +11 -0
- package/dist/host/services/uuid.js +15 -0
- package/dist/host/types.d.ts +21 -5
- package/package.json +1 -1
- package/skill/README.md +1 -1
- package/skill/SKILL.md +30 -17
- package/skill/package.json +1 -1
- package/skill/references/state-model.md +12 -10
- package/skill/references/troubleshooting.md +19 -7
- package/skill/scripts/ledgerkit/actions/atom.py +2 -2
- package/skill/scripts/ledgerkit/actions/bootstrap.py +9 -2
- package/skill/scripts/ledgerkit/actions/claim.py +7 -6
- package/skill/scripts/ledgerkit/actions/close_task.py +17 -12
- package/skill/scripts/ledgerkit/actions/guard.py +38 -16
- package/skill/scripts/ledgerkit/actions/handoff.py +24 -8
- package/skill/scripts/ledgerkit/actions/init_identity.py +90 -0
- package/skill/scripts/ledgerkit/actions/list_tasks.py +21 -3
- package/skill/scripts/ledgerkit/actions/log_progress.py +5 -2
- package/skill/scripts/ledgerkit/actions/new_task.py +11 -7
- package/skill/scripts/ledgerkit/actions/query.py +4 -2
- package/skill/scripts/ledgerkit/actions/query_history.py +55 -9
- package/skill/scripts/ledgerkit/actions/registry.py +1 -1
- package/skill/scripts/ledgerkit/actions/release.py +25 -4
- package/skill/scripts/ledgerkit/actions/set_task.py +18 -7
- package/skill/scripts/ledgerkit/actions/validate.py +0 -4
- package/skill/scripts/ledgerkit/core/history_md.py +47 -250
- package/skill/scripts/ledgerkit/core/identity.py +34 -7
- package/skill/scripts/ledgerkit/core/labels.py +0 -1
- package/skill/scripts/ledgerkit/core/paths.py +0 -1
- package/skill/scripts/ledgerkit/core/worklog_md.py +23 -3
- package/skill/scripts/ledgerkit/env.py +70 -71
- package/skill/scripts/ledgerkit/shell/cli.py +60 -3
- package/skill/scripts/ledgerkit/shell/gitops.py +14 -1
- package/skill/scripts/ledgerkit/shell/render.py +3 -2
- package/skill/scripts/ledgerkit/shell/runner.py +1 -1
- package/skill/scripts/ledgerkit/store/history_store.py +26 -81
- package/skill/scripts/ledgerkit/store/owners_index.py +16 -3
- package/skill/scripts/ledgerkit/store/task_store.py +2 -2
package/dist/client.js
CHANGED
|
@@ -7,18 +7,32 @@ window.__ModuleLoader__.load({
|
|
|
7
7
|
let react = require("react");
|
|
8
8
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
9
9
|
//#region src/client/rows.ts
|
|
10
|
+
/**
|
|
11
|
+
* 界面上显示人名的**唯一**口径:显示名(`owner_name` / `creator_name`)优先,
|
|
12
|
+
* 旧数据 / 名册里没名字才退回 uuid。**只用于显示与搜索** —— 归属判定一律比 uuid(见 `isMine`)。
|
|
13
|
+
*/
|
|
14
|
+
function displayName(name, uuid) {
|
|
15
|
+
const label = (name ?? "").trim();
|
|
16
|
+
return label !== "" ? label : (uuid ?? "").trim();
|
|
17
|
+
}
|
|
10
18
|
/** 关键字命中(标题 / 任务号 / 人 / 分类 / 标签;已结案另含「完成了什么」)。 */
|
|
11
19
|
function hitKeyword(keyword, parts) {
|
|
12
20
|
const needle = keyword.trim().toLowerCase();
|
|
13
21
|
if (needle === "") return true;
|
|
14
22
|
return parts.some((part) => part?.toLowerCase().includes(needle) === true);
|
|
15
23
|
}
|
|
16
|
-
/**
|
|
24
|
+
/** uuid 比较:两边都 trim + 小写(身份键不分大小写,与脚本 `normalize` 同口径)。 */
|
|
25
|
+
function sameUuid(a, b) {
|
|
26
|
+
const left = (a ?? "").trim().toLowerCase();
|
|
27
|
+
const right = (b ?? "").trim().toLowerCase();
|
|
28
|
+
return left !== "" && left === right;
|
|
29
|
+
}
|
|
30
|
+
/** 「我的」判定:owner = 本机身份 uuid,且状态是进行中(blocked 是旧数据,照收;与 host 同口径)。 */
|
|
17
31
|
function isMine(task, board) {
|
|
18
32
|
if (board === null) return false;
|
|
19
33
|
const identity = board.identities[task.workspace.id] ?? null;
|
|
20
34
|
if (identity === null || identity === "") return false;
|
|
21
|
-
return task.owner
|
|
35
|
+
return sameUuid(task.owner, identity) && (task.status === "doing" || task.status === "blocked");
|
|
22
36
|
}
|
|
23
37
|
function resolveActions(task, board) {
|
|
24
38
|
const mine = isMine(task, board);
|
|
@@ -88,8 +102,8 @@ window.__ModuleLoader__.load({
|
|
|
88
102
|
const mineRows = board.tasks.filter((task) => isMine(task, board)).filter((task) => query.workspace === "" || task.workspace.id === query.workspace).filter((task) => hitKeyword(query.keyword, [
|
|
89
103
|
task.title,
|
|
90
104
|
task.id,
|
|
91
|
-
task.owner,
|
|
92
|
-
task.creator,
|
|
105
|
+
displayName(task.owner_name, task.owner),
|
|
106
|
+
displayName(task.creator_name, task.creator),
|
|
93
107
|
task.category,
|
|
94
108
|
...task.tags ?? []
|
|
95
109
|
])).sort((a, b) => String(b.created ?? b.started ?? "").localeCompare(String(a.created ?? a.started ?? ""))).map((task) => ({
|
|
@@ -98,7 +112,7 @@ window.__ModuleLoader__.load({
|
|
|
98
112
|
task,
|
|
99
113
|
mine: true
|
|
100
114
|
}));
|
|
101
|
-
const rest = query.scope === "mine" ? [] : board.tasks.filter((task) => statusHit(task, query.status)).filter((task) => hitKeyword(query.othersKeyword, [task.title, task.owner]));
|
|
115
|
+
const rest = query.scope === "mine" ? [] : board.tasks.filter((task) => statusHit(task, query.status)).filter((task) => hitKeyword(query.othersKeyword, [task.title, displayName(task.owner_name, task.owner)]));
|
|
102
116
|
const byWorkspace = /* @__PURE__ */ new Map();
|
|
103
117
|
for (const task of rest) {
|
|
104
118
|
const entry = byWorkspace.get(task.workspace.id) ?? {
|
|
@@ -1097,9 +1111,9 @@ body[data-ds-dark-theme]{
|
|
|
1097
1111
|
*/
|
|
1098
1112
|
/** 行标题:在办 = 任务名(缺则任务号);已结案 = 任务包名(缺则「完成了什么」首句)。 */
|
|
1099
1113
|
function titleOf(row) {
|
|
1100
|
-
if (row.kind === "task") return row.task.title
|
|
1101
|
-
const title = row.record.workpackage
|
|
1102
|
-
return title !==
|
|
1114
|
+
if (row.kind === "task") return row.task.title || row.task.id;
|
|
1115
|
+
const title = row.record.workpackage || row.record.summary || "";
|
|
1116
|
+
return title !== "" ? title : row.record.src ?? "—";
|
|
1103
1117
|
}
|
|
1104
1118
|
/** 状态语义(异常优先:停滞 > 逾期 > 积压;三者都是 host 按时间算出来的,不是状态)。
|
|
1105
1119
|
* 只决定圆点 / 左缘色条这类**单色位**——标签可以多枚,见 MARKS。 */
|
|
@@ -1142,7 +1156,7 @@ body[data-ds-dark-theme]{
|
|
|
1142
1156
|
const detailTip = (which) => {
|
|
1143
1157
|
if (row.kind !== "task") return void 0;
|
|
1144
1158
|
const { task } = row;
|
|
1145
|
-
const owner = task.owner
|
|
1159
|
+
const owner = displayName(task.owner_name, task.owner);
|
|
1146
1160
|
const who = owner === "" ? t("ownerUnclaimed") : `@${owner}`;
|
|
1147
1161
|
const started = stamp(task.started ?? task.created);
|
|
1148
1162
|
const updated = stamp(task.updated ?? task.started ?? task.created);
|
|
@@ -1215,14 +1229,15 @@ body[data-ds-dark-theme]{
|
|
|
1215
1229
|
title: titleOf(row)
|
|
1216
1230
|
}, titleOf(row)));
|
|
1217
1231
|
if (variant === "others") {
|
|
1218
|
-
const creator = isTask ? row.task.creator : row.record.
|
|
1232
|
+
const creator = isTask ? row.task.creator : row.record.creator;
|
|
1219
1233
|
const owner = isTask ? row.task.owner : null;
|
|
1234
|
+
const creatorLabel = displayName(isTask ? row.task.creator_name : row.record.creator_name, creator);
|
|
1220
1235
|
const hasOwner = !(owner === null || owner === void 0 || owner === "");
|
|
1221
|
-
const who =
|
|
1236
|
+
const who = creatorLabel === "" ? "—" : `@${creatorLabel}`;
|
|
1222
1237
|
const createdOk = created !== null && created !== void 0 && Date.parse(created) >= 0;
|
|
1223
1238
|
const startedOk = isTask && row.task.started !== null && row.task.started !== void 0 && Date.parse(row.task.started) >= 0;
|
|
1224
1239
|
const ownerTip = t("startedAt", {
|
|
1225
|
-
who:
|
|
1240
|
+
who: displayName(isTask ? row.task.owner_name : null, owner),
|
|
1226
1241
|
when: startedOk ? formatDateTime(String(row.task.started)) : t("timeUnknown")
|
|
1227
1242
|
});
|
|
1228
1243
|
const tagLine = (0, react.createElement)("div", { className: "dtl-orow__tags" }, ...statusTags, tags.map((tag) => (0, react.createElement)(Tag, {
|
|
@@ -1230,7 +1245,7 @@ body[data-ds-dark-theme]{
|
|
|
1230
1245
|
text: `#${tag}`
|
|
1231
1246
|
})));
|
|
1232
1247
|
return (0, react.createElement)("div", { className: "dtl-orow" }, (0, react.createElement)("div", { className: "dtl-orow__row" }, (0, react.createElement)("span", { className: `dtl-dot dtl-dot--${tone}` }), (0, react.createElement)("div", { className: "dtl-tcell dtl-tcell--title" }, orowTitleLine, tagLine), (0, react.createElement)("span", { className: "dtl-tcell dtl-tcell--status" }, hasOwner ? (0, react.createElement)(Tag, {
|
|
1233
|
-
text: `@${
|
|
1248
|
+
text: `@${displayName(isTask ? row.task.owner_name : null, owner)}`,
|
|
1234
1249
|
tone: "person",
|
|
1235
1250
|
title: ownerTip
|
|
1236
1251
|
}) : null), (0, react.createElement)("span", { className: "dtl-orow__slot" }, (0, react.createElement)("span", { className: "dtl-orow__created" }, t("createdAt", {
|
|
@@ -1243,7 +1258,7 @@ body[data-ds-dark-theme]{
|
|
|
1243
1258
|
const startRaw = row.task.started ?? row.task.created;
|
|
1244
1259
|
if (startRaw !== void 0 && startRaw !== null && startRaw !== "" && Date.parse(startRaw) >= 0) parts.push(`${formatDateTime(startRaw).slice(0, 10)} ${t("fieldStarted")}`);
|
|
1245
1260
|
if (row.task.ageDays !== null && row.task.ageDays !== void 0) parts.push(row.task.ageDays === 0 ? t("ageToday") : t("ageDaysText", { n: row.task.ageDays }));
|
|
1246
|
-
} else parts.push(`${t("fieldFinished")} ${formatDateTime(row.record.time
|
|
1261
|
+
} else parts.push(`${t("fieldFinished")} ${formatDateTime(row.record.time || row.record.created || "", { fallback: t("timeUnknown") })}`);
|
|
1247
1262
|
return (0, react.createElement)("div", { className: "dtl-taskrow" }, (0, react.createElement)("div", { className: "dtl-taskrow__row" }, (0, react.createElement)("span", { className: `dtl-rail dtl-rail--${tone}` }), (0, react.createElement)("div", { style: {
|
|
1248
1263
|
flex: "1 1 auto",
|
|
1249
1264
|
minWidth: 0
|