dsh-task-ledger 0.0.77 → 0.0.79

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.
Files changed (56) hide show
  1. package/dist/client.js +29 -14
  2. package/dist/client.js.map +1 -1
  3. package/dist/host/board.d.ts +2 -2
  4. package/dist/host/board.js +2 -2
  5. package/dist/host/repositories/cache.js +18 -2
  6. package/dist/host/repositories/identity.repository.d.ts +3 -8
  7. package/dist/host/repositories/identity.repository.js +32 -23
  8. package/dist/host/repositories/ledger.repository.d.ts +7 -3
  9. package/dist/host/repositories/ledger.repository.js +23 -14
  10. package/dist/host/repositories/records.js +20 -1
  11. package/dist/host/repositories/runner.d.ts +2 -2
  12. package/dist/host/repositories/runner.js +1 -1
  13. package/dist/host/routes.js +40 -11
  14. package/dist/host/services/home.service.d.ts +2 -2
  15. package/dist/host/services/home.service.js +7 -4
  16. package/dist/host/services/ledger-write.service.d.ts +4 -4
  17. package/dist/host/services/ledger-write.service.js +7 -7
  18. package/dist/host/services/trend.service.d.ts +2 -2
  19. package/dist/host/services/trend.service.js +9 -10
  20. package/dist/host/services/uuid.d.ts +11 -0
  21. package/dist/host/services/uuid.js +15 -0
  22. package/dist/host/types.d.ts +20 -4
  23. package/package.json +2 -2
  24. package/skill/README.md +2 -2
  25. package/skill/SKILL.md +32 -19
  26. package/skill/package.json +1 -1
  27. package/skill/references/state-model.md +9 -7
  28. package/skill/references/troubleshooting.md +19 -7
  29. package/skill/scripts/ledgerkit/actions/atom.py +2 -2
  30. package/skill/scripts/ledgerkit/actions/bootstrap.py +9 -2
  31. package/skill/scripts/ledgerkit/actions/claim.py +7 -6
  32. package/skill/scripts/ledgerkit/actions/close_task.py +13 -12
  33. package/skill/scripts/ledgerkit/actions/guard.py +38 -16
  34. package/skill/scripts/ledgerkit/actions/handoff.py +19 -8
  35. package/skill/scripts/ledgerkit/actions/init_identity.py +90 -0
  36. package/skill/scripts/ledgerkit/actions/list_tasks.py +21 -3
  37. package/skill/scripts/ledgerkit/actions/log_progress.py +5 -2
  38. package/skill/scripts/ledgerkit/actions/new_task.py +11 -7
  39. package/skill/scripts/ledgerkit/actions/query.py +4 -2
  40. package/skill/scripts/ledgerkit/actions/query_history.py +48 -9
  41. package/skill/scripts/ledgerkit/actions/registry.py +1 -1
  42. package/skill/scripts/ledgerkit/actions/release.py +25 -4
  43. package/skill/scripts/ledgerkit/actions/set_task.py +18 -7
  44. package/skill/scripts/ledgerkit/actions/validate.py +0 -4
  45. package/skill/scripts/ledgerkit/core/history_md.py +20 -245
  46. package/skill/scripts/ledgerkit/core/identity.py +20 -7
  47. package/skill/scripts/ledgerkit/core/labels.py +0 -1
  48. package/skill/scripts/ledgerkit/core/paths.py +0 -1
  49. package/skill/scripts/ledgerkit/env.py +70 -71
  50. package/skill/scripts/ledgerkit/shell/cli.py +60 -3
  51. package/skill/scripts/ledgerkit/shell/gitops.py +14 -1
  52. package/skill/scripts/ledgerkit/shell/render.py +3 -2
  53. package/skill/scripts/ledgerkit/shell/runner.py +1 -1
  54. package/skill/scripts/ledgerkit/store/history_store.py +23 -80
  55. package/skill/scripts/ledgerkit/store/owners_index.py +16 -3
  56. 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
- /** 「我的」判定:owner = 该工作区的当前 git 身份,且状态是进行中(blocked 是旧数据,照收;与 host 同口径)。 */
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 === identity && (task.status === "doing" || task.status === "blocked");
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 ?? row.task.id;
1101
- const title = row.record.workpackage ?? row.record.summary;
1102
- return title !== void 0 && title !== "" ? title : row.record.src ?? "—";
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.owner;
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 = creator === null || creator === void 0 || creator === "" ? "—" : `@${creator}`;
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: String(owner),
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: `@${String(owner)}`,
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 ?? row.record.created ?? "", { fallback: t("timeUnknown") })}`);
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