dsh-task-ledger 0.0.112 → 0.0.114

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 (47) hide show
  1. package/dist/client.js +50739 -1529
  2. package/dist/client.js.map +1 -1
  3. package/dist/host/errors.d.ts +2 -2
  4. package/dist/host/repositories/cache.d.ts +2 -3
  5. package/dist/host/repositories/cache.js +1 -2
  6. package/dist/host/repositories/identity.repository.d.ts +8 -2
  7. package/dist/host/repositories/identity.repository.js +9 -29
  8. package/dist/host/repositories/ledger.repository.d.ts +12 -22
  9. package/dist/host/repositories/ledger.repository.js +39 -58
  10. package/dist/host/repositories/records.d.ts +1 -11
  11. package/dist/host/repositories/records.js +16 -42
  12. package/dist/host/repositories/runner.d.ts +0 -30
  13. package/dist/host/repositories/runner.js +0 -23
  14. package/dist/host/repositories/stats.repository.d.ts +36 -0
  15. package/dist/host/repositories/stats.repository.js +86 -0
  16. package/dist/host/routes.d.ts +4 -25
  17. package/dist/host/routes.js +7 -384
  18. package/dist/host/services/dates.d.ts +3 -24
  19. package/dist/host/services/dates.js +3 -63
  20. package/dist/host/services/stats.service.d.ts +7 -0
  21. package/dist/host/services/stats.service.js +134 -0
  22. package/dist/host/skill/registration.d.ts +0 -3
  23. package/dist/host/skill/registration.js +0 -3
  24. package/dist/host/types.d.ts +70 -126
  25. package/dist/host/workspace.d.ts +3 -4
  26. package/dist/host/workspace.js +5 -5
  27. package/dist/index.js +2 -33
  28. package/package.json +2 -2
  29. package/skill/SKILL.md +5 -4
  30. package/skill/package.json +1 -1
  31. package/skill/scripts/bin/ledger-darwin-arm64 +0 -0
  32. package/skill/scripts/bin/ledger-linux-amd64 +0 -0
  33. package/skill/scripts/bin/ledger-windows-amd64.exe +0 -0
  34. package/dist/host/board.d.ts +0 -20
  35. package/dist/host/board.js +0 -29
  36. package/dist/host/services/history.service.d.ts +0 -27
  37. package/dist/host/services/history.service.js +0 -72
  38. package/dist/host/services/home.service.d.ts +0 -23
  39. package/dist/host/services/home.service.js +0 -91
  40. package/dist/host/services/ledger-write.service.d.ts +0 -10
  41. package/dist/host/services/ledger-write.service.js +0 -32
  42. package/dist/host/services/session.service.d.ts +0 -110
  43. package/dist/host/services/session.service.js +0 -155
  44. package/dist/host/services/trend.service.d.ts +0 -36
  45. package/dist/host/services/trend.service.js +0 -162
  46. package/dist/host/services/uuid.d.ts +0 -11
  47. package/dist/host/services/uuid.js +0 -15
@@ -1,162 +0,0 @@
1
- /**
2
- * 首页**慢路径**用例:近 8 周趋势 + 四个自然周期。
3
- * 读 history(months=RECENT_MONTHS)+ 在办 + 本机身份——首屏不等它(异步/按需拉)。
4
- *
5
- * ⚠️ 窗口必须是 13 个月而不是 2:8 周桶在月初会横跨 3 个自然月(如 10 月第 1 周回溯到 8 月),
6
- * `--months` 是**文件级**过滤,缩到 2 会静默漏掉 8 月结案记录、趋势少算(2026-10-18 架构评审结论)。
7
- */
8
- import { settleWorkspaces } from "../errors.js";
9
- import { sameUuid } from "./uuid.js";
10
- import { getCurrentIdentity } from "../repositories/identity.repository.js";
11
- import { readHistory, readTasks } from "../repositories/ledger.repository.js";
12
- import { buildWeeks, dayOf, inWindow, mondayOf, monthWindow, weekWindow, ymd, } from "./dates.js";
13
- /** 历史窗口:只读最近 13 个月的文件(2026-10-17 拍板;脚本默认读全部,窗口由插件显式传)。 */
14
- export const RECENT_MONTHS = 13;
15
- /** 趋势图桶数:近 8 周(2026-10-17 定稿)。 */
16
- export const WEEKLY_WEEKS = 8;
17
- /** 慢路径读法:单工作区 readTasks + readHistory(months) + 本机身份(并行;供 settle 逐工作区调)。 */
18
- export async function readTrendScope(workspace) {
19
- const [tasks, history, identity] = await Promise.all([
20
- readTasks(workspace),
21
- readHistory(workspace, { months: RECENT_MONTHS }),
22
- getCurrentIdentity(workspace),
23
- ]);
24
- return {
25
- workspace,
26
- tasks,
27
- history: history.records,
28
- identity,
29
- warnings: history.warnings,
30
- };
31
- }
32
- /**
33
- * 近 N 周分组桶(完成按结案时间、新增按创建时间)× 所有 / 我的(纯函数)。
34
- *
35
- * 新增必须**合并两个来源**:已结案的任务被 close 移出 progress.json,只在 history 里;
36
- * 在办的只在 progress.json 里。两者不相交(close 是移动),合并即全集、不会重复计。
37
- * remaining:某任务在「第 i 周截止时」仍未完成 ⇔ 创建 ≤ weekEnd_i 且(未结案 或 结案 > weekEnd_i)。
38
- */
39
- export function computeClosedSummary(scopes, now) {
40
- const weeks = buildWeeks(WEEKLY_WEEKS, now);
41
- const weekEnds = weeks.map((slot) => slot.end);
42
- const make = () => new Map(weeks.map((slot) => [slot.week, { done: 0, created: 0, remaining: 0 }]));
43
- const bucketsAll = make();
44
- const bucketsMine = make();
45
- const bump = (map, week, field) => {
46
- const bucket = map.get(week);
47
- if (bucket !== undefined)
48
- map.set(week, { ...bucket, [field]: bucket[field] + 1 });
49
- };
50
- const bumpRemaining = (map, createdDay, closeDay) => {
51
- if (createdDay === null)
52
- return;
53
- for (let i = 0; i < weeks.length; i += 1) {
54
- if (createdDay <= weekEnds[i] &&
55
- (closeDay === null || closeDay > weekEnds[i])) {
56
- const bucket = map.get(weeks[i].week);
57
- if (bucket !== undefined)
58
- bucket.remaining += 1;
59
- }
60
- }
61
- };
62
- for (const scope of scopes) {
63
- const identity = scope.identity;
64
- for (const task of scope.tasks) {
65
- const created = dayOf(task.created);
66
- if (created === null)
67
- continue;
68
- const week = ymd(mondayOf(created));
69
- const createdMine = sameUuid(task.creator, identity);
70
- bump(bucketsAll, week, "created");
71
- if (createdMine)
72
- bump(bucketsMine, week, "created");
73
- const ownedMine = sameUuid(task.owner, identity);
74
- bumpRemaining(bucketsAll, created, null);
75
- if (ownedMine)
76
- bumpRemaining(bucketsMine, created, null);
77
- }
78
- for (const record of scope.history) {
79
- const closed = dayOf(record.time);
80
- if (closed !== null) {
81
- const week = ymd(mondayOf(closed));
82
- bump(bucketsAll, week, "done");
83
- if (sameUuid(record.owner, identity))
84
- bump(bucketsMine, week, "done");
85
- }
86
- const created = dayOf(record.created);
87
- if (created !== null) {
88
- const week = ymd(mondayOf(created));
89
- bump(bucketsAll, week, "created");
90
- // 新增(我的)= 我创建的(creator);旧 8 列历史无 creator 列 ⇒ 兜底 owner
91
- const createdMine = sameUuid(record.creator, identity) ||
92
- ((record.creator ?? null) === null && sameUuid(record.owner, identity));
93
- if (createdMine)
94
- bump(bucketsMine, week, "created");
95
- }
96
- const ownedMine = sameUuid(record.owner, identity);
97
- bumpRemaining(bucketsAll, created, closed);
98
- if (ownedMine)
99
- bumpRemaining(bucketsMine, created, closed);
100
- }
101
- }
102
- const toBuckets = (map) => weeks.map((slot, i) => ({
103
- week: slot.week,
104
- end: weekEnds[i],
105
- ...(map.get(slot.week) ?? { done: 0, created: 0, remaining: 0 }),
106
- }));
107
- return {
108
- weekly: { all: toBuckets(bucketsAll), mine: toBuckets(bucketsMine) },
109
- };
110
- }
111
- /** 四个自然周期(只算「全部工作区」范围;图表切换不带动卡片)——纯函数。 */
112
- export function computeTrendPeriods(scopes, now) {
113
- const windows = {
114
- thisWeek: weekWindow(0, now),
115
- lastWeek: weekWindow(-1, now),
116
- thisMonth: monthWindow(0, now),
117
- lastMonth: monthWindow(-1, now),
118
- };
119
- const doneEntries = scopes.flatMap((scope) => scope.history.map((record) => ({
120
- day: dayOf(record.time),
121
- owner: record.owner ?? null,
122
- })));
123
- const createdEntries = scopes.flatMap((scope) => [
124
- ...scope.tasks.map((task) => ({
125
- day: dayOf(task.created),
126
- owner: task.owner ?? null,
127
- })),
128
- ...scope.history.map((record) => ({
129
- day: dayOf(record.created),
130
- owner: record.owner ?? null,
131
- })),
132
- ]);
133
- const period = (window) => ({
134
- done: doneEntries.filter((entry) => inWindow(entry.day, window)).length,
135
- created: createdEntries.filter((entry) => inWindow(entry.day, window))
136
- .length,
137
- from: window.from,
138
- to: window.to,
139
- });
140
- return {
141
- thisWeek: period(windows.thisWeek),
142
- lastWeek: period(windows.lastWeek),
143
- thisMonth: period(windows.thisMonth),
144
- lastMonth: period(windows.lastMonth),
145
- };
146
- }
147
- /** 慢路径端点:趋势 + 周期(读 history)。异步加载,首屏不等。单工作区坏 ⇒ 进 degraded。 */
148
- export async function getTrend(workspaces) {
149
- const now = new Date();
150
- const { data: scopes, degraded } = await settleWorkspaces(workspaces, "history", readTrendScope, (rows) => rows);
151
- return {
152
- closed: computeClosedSummary(scopes, now),
153
- trend: computeTrendPeriods(scopes, now),
154
- degraded,
155
- // 被脚本跳过的历史行(列数不对 / 时间不合法):数字已经少算了,必须让界面说出口
156
- warnings: scopes.flatMap((scope) => scope.warnings),
157
- };
158
- }
159
- /** 趋势端点用的历史 filter(窗口由本模块策略决定,repository 零默认值注入)。 */
160
- export function trendHistoryFilter(extra = {}) {
161
- return { months: RECENT_MONTHS, ...extra };
162
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * 身份比较的唯一口径:**两边都 trim + 小写再比**。
3
- *
4
- * 台账里的 owner / creator 存的是 uuid,本机身份也取 uuid;但两边来源不同
5
- * (identity.json 可能是手写的、台账里可能是旧版本写的),大小写不一定一致。
6
- * 脚本侧 `core/identity.normalize` 就是这么比的,这里必须同口径,
7
- * 否则脚本说「是你的」,界面说「不是你的」。
8
- *
9
- * 空值一律不算相等(`"" === ""` 会让「没 init」被误判成「是我的」)。
10
- */
11
- export declare function sameUuid(a: string | null | undefined, b: string | null | undefined): boolean;
@@ -1,15 +0,0 @@
1
- /**
2
- * 身份比较的唯一口径:**两边都 trim + 小写再比**。
3
- *
4
- * 台账里的 owner / creator 存的是 uuid,本机身份也取 uuid;但两边来源不同
5
- * (identity.json 可能是手写的、台账里可能是旧版本写的),大小写不一定一致。
6
- * 脚本侧 `core/identity.normalize` 就是这么比的,这里必须同口径,
7
- * 否则脚本说「是你的」,界面说「不是你的」。
8
- *
9
- * 空值一律不算相等(`"" === ""` 会让「没 init」被误判成「是我的」)。
10
- */
11
- export function sameUuid(a, b) {
12
- const left = (a ?? "").trim().toLowerCase();
13
- const right = (b ?? "").trim().toLowerCase();
14
- return left !== "" && left === right;
15
- }