@skillfm/local 2.7.3 → 2.7.5
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/checkup/daily-push.d.ts +29 -0
- package/dist/checkup/daily-push.d.ts.map +1 -0
- package/dist/checkup/daily-push.js +86 -0
- package/dist/checkup/daily-push.js.map +1 -0
- package/dist/checkup/dimension-1-usage.d.ts +22 -0
- package/dist/checkup/dimension-1-usage.d.ts.map +1 -0
- package/dist/checkup/dimension-1-usage.js +115 -0
- package/dist/checkup/dimension-1-usage.js.map +1 -0
- package/dist/checkup/dimension-3-files.d.ts +36 -0
- package/dist/checkup/dimension-3-files.d.ts.map +1 -0
- package/dist/checkup/dimension-3-files.js +276 -0
- package/dist/checkup/dimension-3-files.js.map +1 -0
- package/dist/checkup/dimension-4-context.d.ts +18 -0
- package/dist/checkup/dimension-4-context.d.ts.map +1 -0
- package/dist/checkup/dimension-4-context.js +177 -0
- package/dist/checkup/dimension-4-context.js.map +1 -0
- package/dist/checkup/index.d.ts +11 -0
- package/dist/checkup/index.d.ts.map +1 -0
- package/dist/checkup/index.js +10 -0
- package/dist/checkup/index.js.map +1 -0
- package/dist/checkup/report.d.ts +26 -0
- package/dist/checkup/report.d.ts.map +1 -0
- package/dist/checkup/report.js +173 -0
- package/dist/checkup/report.js.map +1 -0
- package/dist/checkup/score.d.ts +27 -0
- package/dist/checkup/score.d.ts.map +1 -0
- package/dist/checkup/score.js +101 -0
- package/dist/checkup/score.js.map +1 -0
- package/dist/checkup/types.d.ts +64 -0
- package/dist/checkup/types.d.ts.map +1 -0
- package/dist/checkup/types.js +5 -0
- package/dist/checkup/types.js.map +1 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +27 -0
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/tools/checkup.d.ts +21 -0
- package/dist/mcp/tools/checkup.d.ts.map +1 -0
- package/dist/mcp/tools/checkup.js +35 -0
- package/dist/mcp/tools/checkup.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +6 -0
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js +47 -0
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/setup-gateway.d.ts +16 -0
- package/dist/mcp/tools/setup-gateway.d.ts.map +1 -0
- package/dist/mcp/tools/setup-gateway.js +79 -0
- package/dist/mcp/tools/setup-gateway.js.map +1 -0
- package/dist/mcp/tools/show-my-usage.d.ts +26 -0
- package/dist/mcp/tools/show-my-usage.d.ts.map +1 -0
- package/dist/mcp/tools/show-my-usage.js +68 -0
- package/dist/mcp/tools/show-my-usage.js.map +1 -0
- package/dist/reconciliation/engine.d.ts +30 -0
- package/dist/reconciliation/engine.d.ts.map +1 -0
- package/dist/reconciliation/engine.js +62 -0
- package/dist/reconciliation/engine.js.map +1 -0
- package/dist/reconciliation/index.d.ts +8 -0
- package/dist/reconciliation/index.d.ts.map +1 -0
- package/dist/reconciliation/index.js +8 -0
- package/dist/reconciliation/index.js.map +1 -0
- package/dist/reconciliation/l1-reconciler.d.ts +29 -0
- package/dist/reconciliation/l1-reconciler.d.ts.map +1 -0
- package/dist/reconciliation/l1-reconciler.js +144 -0
- package/dist/reconciliation/l1-reconciler.js.map +1 -0
- package/dist/reconciliation/l2-reconciler.d.ts +21 -0
- package/dist/reconciliation/l2-reconciler.d.ts.map +1 -0
- package/dist/reconciliation/l2-reconciler.js +241 -0
- package/dist/reconciliation/l2-reconciler.js.map +1 -0
- package/dist/reconciliation/types.d.ts +49 -0
- package/dist/reconciliation/types.d.ts.map +1 -0
- package/dist/reconciliation/types.js +9 -0
- package/dist/reconciliation/types.js.map +1 -0
- package/dist/save-token/e1-router.d.ts +7 -0
- package/dist/save-token/e1-router.d.ts.map +1 -0
- package/dist/save-token/e1-router.js +112 -0
- package/dist/save-token/e1-router.js.map +1 -0
- package/dist/save-token/e2-cache.d.ts +7 -0
- package/dist/save-token/e2-cache.d.ts.map +1 -0
- package/dist/save-token/e2-cache.js +128 -0
- package/dist/save-token/e2-cache.js.map +1 -0
- package/dist/save-token/e3-batch.d.ts +7 -0
- package/dist/save-token/e3-batch.d.ts.map +1 -0
- package/dist/save-token/e3-batch.js +80 -0
- package/dist/save-token/e3-batch.js.map +1 -0
- package/dist/save-token/gateway-setup.d.ts +27 -0
- package/dist/save-token/gateway-setup.d.ts.map +1 -0
- package/dist/save-token/gateway-setup.js +200 -0
- package/dist/save-token/gateway-setup.js.map +1 -0
- package/dist/save-token/index.d.ts +13 -0
- package/dist/save-token/index.d.ts.map +1 -0
- package/dist/save-token/index.js +23 -0
- package/dist/save-token/index.js.map +1 -0
- package/dist/save-token/types.d.ts +46 -0
- package/dist/save-token/types.d.ts.map +1 -0
- package/dist/save-token/types.js +5 -0
- package/dist/save-token/types.js.map +1 -0
- package/dist/usage-local/index.d.ts +34 -0
- package/dist/usage-local/index.d.ts.map +1 -0
- package/dist/usage-local/index.js +33 -0
- package/dist/usage-local/index.js.map +1 -0
- package/dist/usage-local/model-pricing.d.ts +42 -0
- package/dist/usage-local/model-pricing.d.ts.map +1 -0
- package/dist/usage-local/model-pricing.js +253 -0
- package/dist/usage-local/model-pricing.js.map +1 -0
- package/dist/usage-local/openclaw-watcher.d.ts +35 -0
- package/dist/usage-local/openclaw-watcher.d.ts.map +1 -0
- package/dist/usage-local/openclaw-watcher.js +190 -0
- package/dist/usage-local/openclaw-watcher.js.map +1 -0
- package/dist/usage-local/plan.d.ts +58 -0
- package/dist/usage-local/plan.d.ts.map +1 -0
- package/dist/usage-local/plan.js +84 -0
- package/dist/usage-local/plan.js.map +1 -0
- package/dist/usage-local/store.d.ts +50 -0
- package/dist/usage-local/store.d.ts.map +1 -0
- package/dist/usage-local/store.js +201 -0
- package/dist/usage-local/store.js.map +1 -0
- package/dist/usage-local/types.d.ts +94 -0
- package/dist/usage-local/types.d.ts.map +1 -0
- package/dist/usage-local/types.js +6 -0
- package/dist/usage-local/types.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/checkup/dimension-4-context.ts
|
|
2
|
+
//
|
|
3
|
+
// 维度 4: 上下文占用 / 一键整理 (PRD §4.4) — AI 时代独有.
|
|
4
|
+
// 检测各 agent harness 的当前 session 上下文 % 用量.
|
|
5
|
+
//
|
|
6
|
+
// MVP: 只 surface OpenClaw (我们已 verify 真 schema), Claude Code/Cursor 后续 batch.
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { homedir } from 'node:os';
|
|
10
|
+
const OPENCLAW_AGENTS_DIR = path.join(homedir(), '.openclaw', 'agents');
|
|
11
|
+
/**
|
|
12
|
+
* 估算 model 的 context window 上限 (粗略, MVP)
|
|
13
|
+
* 后续可改成跟 model-pricing.ts 联动 (按 modelId 真查上限)
|
|
14
|
+
*/
|
|
15
|
+
function estimateContextWindow(modelId) {
|
|
16
|
+
const m = modelId.toLowerCase();
|
|
17
|
+
if (m.includes('claude') && m.includes('1m'))
|
|
18
|
+
return 1_000_000;
|
|
19
|
+
if (m.includes('claude'))
|
|
20
|
+
return 200_000;
|
|
21
|
+
if (m.includes('gpt-4o') || m.includes('o1'))
|
|
22
|
+
return 128_000;
|
|
23
|
+
if (m.includes('gpt-4-turbo'))
|
|
24
|
+
return 128_000;
|
|
25
|
+
if (m.includes('minimax'))
|
|
26
|
+
return 200_000;
|
|
27
|
+
if (m.includes('deepseek'))
|
|
28
|
+
return 128_000;
|
|
29
|
+
if (m.includes('qwen'))
|
|
30
|
+
return 128_000;
|
|
31
|
+
if (m.includes('doubao'))
|
|
32
|
+
return 128_000;
|
|
33
|
+
if (m.includes('kimi'))
|
|
34
|
+
return 200_000;
|
|
35
|
+
return 128_000; // fallback
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 扫 OpenClaw agents/<id>/sessions/*.trajectory.jsonl 的最后一条 model.completed
|
|
39
|
+
* 看当前 session 累计 token + 估算 context window 占用
|
|
40
|
+
*/
|
|
41
|
+
async function scanOpenClawSessions() {
|
|
42
|
+
if (!fs.existsSync(OPENCLAW_AGENTS_DIR))
|
|
43
|
+
return [];
|
|
44
|
+
const out = [];
|
|
45
|
+
const agents = await fs.promises.readdir(OPENCLAW_AGENTS_DIR, { withFileTypes: true });
|
|
46
|
+
for (const agent of agents) {
|
|
47
|
+
if (!agent.isDirectory())
|
|
48
|
+
continue;
|
|
49
|
+
const sessionsDir = path.join(OPENCLAW_AGENTS_DIR, agent.name, 'sessions');
|
|
50
|
+
if (!fs.existsSync(sessionsDir))
|
|
51
|
+
continue;
|
|
52
|
+
const files = await fs.promises.readdir(sessionsDir);
|
|
53
|
+
for (const f of files) {
|
|
54
|
+
if (!f.endsWith('.trajectory.jsonl'))
|
|
55
|
+
continue;
|
|
56
|
+
const filePath = path.join(sessionsDir, f);
|
|
57
|
+
const status = await readLastModelCompleted(filePath);
|
|
58
|
+
if (status)
|
|
59
|
+
out.push(status);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 读 trajectory.jsonl 最后一个 model.completed event
|
|
66
|
+
* 返 ContextStatus (含 input/output/cacheRead 加总作为当前 context size 估算)
|
|
67
|
+
*/
|
|
68
|
+
async function readLastModelCompleted(filePath) {
|
|
69
|
+
try {
|
|
70
|
+
// tail 100KB (大多数 jsonl session 是 5-10MB, 后 100KB 足够找最近 event)
|
|
71
|
+
const stat = await fs.promises.stat(filePath);
|
|
72
|
+
const readSize = Math.min(stat.size, 100 * 1024);
|
|
73
|
+
const startOffset = stat.size - readSize;
|
|
74
|
+
const buf = Buffer.alloc(readSize);
|
|
75
|
+
const fd = await fs.promises.open(filePath, 'r');
|
|
76
|
+
try {
|
|
77
|
+
await fd.read(buf, 0, readSize, startOffset);
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
await fd.close();
|
|
81
|
+
}
|
|
82
|
+
const text = buf.toString('utf-8');
|
|
83
|
+
const lines = text.split('\n').reverse();
|
|
84
|
+
let modelId = '';
|
|
85
|
+
let provider = '';
|
|
86
|
+
let lastUsage = null;
|
|
87
|
+
let turn_count = 0;
|
|
88
|
+
for (const line of lines) {
|
|
89
|
+
if (!line.trim().startsWith('{'))
|
|
90
|
+
continue;
|
|
91
|
+
try {
|
|
92
|
+
const ev = JSON.parse(line);
|
|
93
|
+
if (ev.type === 'model.completed' && ev.data?.usage) {
|
|
94
|
+
turn_count += 1;
|
|
95
|
+
if (!lastUsage) {
|
|
96
|
+
lastUsage = ev.data.usage;
|
|
97
|
+
modelId = ev.modelId ?? '';
|
|
98
|
+
provider = ev.provider ?? '';
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// skip
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (!lastUsage)
|
|
107
|
+
return null;
|
|
108
|
+
// 当前 context size ~ input + cacheRead (system prompt + history)
|
|
109
|
+
const current_tokens = (lastUsage.input ?? 0) + (lastUsage.cacheRead ?? 0);
|
|
110
|
+
const max = estimateContextWindow(modelId);
|
|
111
|
+
return {
|
|
112
|
+
agent_harness: 'openclaw',
|
|
113
|
+
session_id: path.basename(filePath, '.trajectory.jsonl'),
|
|
114
|
+
current_tokens,
|
|
115
|
+
context_window_max: max,
|
|
116
|
+
utilization_pct: (current_tokens / max) * 100,
|
|
117
|
+
turn_count,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export async function checkDimensionContext() {
|
|
125
|
+
const sessions = await scanOpenClawSessions();
|
|
126
|
+
const findings = [];
|
|
127
|
+
let severity = 'healthy';
|
|
128
|
+
// 找最严重的 session (占比最高)
|
|
129
|
+
const sorted = sessions.sort((a, b) => b.utilization_pct - a.utilization_pct);
|
|
130
|
+
const worst = sorted[0];
|
|
131
|
+
if (worst) {
|
|
132
|
+
if (worst.utilization_pct > 90) {
|
|
133
|
+
findings.push({
|
|
134
|
+
headline: `${worst.agent_harness} session 上下文 ${worst.utilization_pct.toFixed(0)}% — 接近爆`,
|
|
135
|
+
severity: 'critical',
|
|
136
|
+
score_deduction: 25,
|
|
137
|
+
fix_label: 'rotate session (新干净 session, 旧 turn summary 进 memory) [Pro 自动]',
|
|
138
|
+
fix_free_allowed: false, // Free 只 surface 提示, Pro 自动 rotate
|
|
139
|
+
estimated_savings: { description: '估省后续 60% input token' },
|
|
140
|
+
});
|
|
141
|
+
severity = 'critical';
|
|
142
|
+
}
|
|
143
|
+
else if (worst.utilization_pct > 80) {
|
|
144
|
+
findings.push({
|
|
145
|
+
headline: `${worst.agent_harness} session 上下文 ${worst.utilization_pct.toFixed(0)}% — 偏高`,
|
|
146
|
+
severity: 'warning',
|
|
147
|
+
score_deduction: 15,
|
|
148
|
+
fix_label: 'rotate session 让 agent 又快又聪明 [Pro 自动]',
|
|
149
|
+
fix_free_allowed: false,
|
|
150
|
+
estimated_savings: { description: '估省后续 40% input token' },
|
|
151
|
+
});
|
|
152
|
+
severity = 'warning';
|
|
153
|
+
}
|
|
154
|
+
else if (worst.turn_count > 30) {
|
|
155
|
+
findings.push({
|
|
156
|
+
headline: `${worst.agent_harness} session 已 ${worst.turn_count} turn — 建议考虑 rotate`,
|
|
157
|
+
severity: 'info',
|
|
158
|
+
score_deduction: 5,
|
|
159
|
+
fix_label: '考虑新开 session [Pro 自动]',
|
|
160
|
+
fix_free_allowed: false,
|
|
161
|
+
});
|
|
162
|
+
severity = 'info';
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const headline = worst
|
|
166
|
+
? `${worst.agent_harness} ${worst.utilization_pct.toFixed(0)}%${sessions.length > 1 ? ` (${sessions.length} session)` : ''}`
|
|
167
|
+
: '无 active session';
|
|
168
|
+
return {
|
|
169
|
+
dimension: 'context',
|
|
170
|
+
severity,
|
|
171
|
+
headline,
|
|
172
|
+
findings,
|
|
173
|
+
pro_locked: false,
|
|
174
|
+
sessions,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=dimension-4-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dimension-4-context.js","sourceRoot":"","sources":["../../src/checkup/dimension-4-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type { DimensionId, Severity, Finding, DimensionStatus, CheckupReport, HealthSnapshot, } from './types.js';
|
|
2
|
+
export { runCheckup, renderMainEntry } from './report.js';
|
|
3
|
+
export type { CheckupDeps } from './report.js';
|
|
4
|
+
export { computeHealthScore, selectTopFocus, computeTrend, loadHealthHistory, appendHealthSnapshot, } from './score.js';
|
|
5
|
+
export { checkDimensionUsage, buildUsageSurfaceLines } from './dimension-1-usage.js';
|
|
6
|
+
export type { UsageDimDeps } from './dimension-1-usage.js';
|
|
7
|
+
export { checkDimensionFiles, executeFileCleanup } from './dimension-3-files.js';
|
|
8
|
+
export { checkDimensionContext } from './dimension-4-context.js';
|
|
9
|
+
export { renderDailyPush, renderAnomalyPush, shouldPushRealtimeAnomaly, pushTimeToCron, DEFAULT_PUSH_CONFIG, } from './daily-push.js';
|
|
10
|
+
export type { DailyPushConfig, PushTime } from './daily-push.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checkup/index.ts"],"names":[],"mappings":"AAIA,YAAY,EACV,WAAW,EACX,QAAQ,EACR,OAAO,EACP,eAAe,EACf,aAAa,EACb,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrF,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,yBAAyB,EACzB,cAAc,EACd,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/checkup/index.ts
|
|
2
|
+
//
|
|
3
|
+
// Checkup public API.
|
|
4
|
+
export { runCheckup, renderMainEntry } from './report.js';
|
|
5
|
+
export { computeHealthScore, selectTopFocus, computeTrend, loadHealthHistory, appendHealthSnapshot, } from './score.js';
|
|
6
|
+
export { checkDimensionUsage, buildUsageSurfaceLines } from './dimension-1-usage.js';
|
|
7
|
+
export { checkDimensionFiles, executeFileCleanup } from './dimension-3-files.js';
|
|
8
|
+
export { checkDimensionContext } from './dimension-4-context.js';
|
|
9
|
+
export { renderDailyPush, renderAnomalyPush, shouldPushRealtimeAnomaly, pushTimeToCron, DEFAULT_PUSH_CONFIG, } from './daily-push.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/checkup/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,sBAAsB;AAUtB,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAErF,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,yBAAyB,EACzB,cAAc,EACd,mBAAmB,GACpB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { LocalUsageStore } from '../usage-local/store.js';
|
|
2
|
+
import type { ReconciliationEngine } from '../reconciliation/index.js';
|
|
3
|
+
import type { CheckupReport } from './types.js';
|
|
4
|
+
export interface CheckupDeps {
|
|
5
|
+
store: LocalUsageStore;
|
|
6
|
+
reconciliationEngine: ReconciliationEngine;
|
|
7
|
+
/** 是否为 Pro 用户 (锁标控制) */
|
|
8
|
+
is_pro: boolean;
|
|
9
|
+
/** 跳过 history 写入 (测试用) */
|
|
10
|
+
skip_persist?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 主入口 — 跑一次全 5 维度体检 → CheckupReport
|
|
14
|
+
*/
|
|
15
|
+
export declare function runCheckup(deps: CheckupDeps): Promise<CheckupReport>;
|
|
16
|
+
/**
|
|
17
|
+
* 主入口 UX 渲染 — 把 CheckupReport 渲染成 < 300 字的中文文本块.
|
|
18
|
+
* V1.4 乔布斯级打磨 (Eric 真测反馈):
|
|
19
|
+
* - 健康度配形容词 (96 ✨ 优秀 / 67 ⚠ 需关注)
|
|
20
|
+
* - 维度 emoji 一致 + Pro 维度折叠成 1 行不重复
|
|
21
|
+
* - "今日 #1" 用 actionable 文案 (含真数字)
|
|
22
|
+
* - 0 MB 文件正向反馈
|
|
23
|
+
* - action button 收到 2-3 个最关键
|
|
24
|
+
*/
|
|
25
|
+
export declare function renderMainEntry(report: CheckupReport): string;
|
|
26
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/checkup/report.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,YAAY,CAAC;AAWjE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,eAAe,CAAC;IACvB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,wBAAwB;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,0BAA0B;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAgE1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CA0D7D"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/checkup/report.ts
|
|
2
|
+
//
|
|
3
|
+
// CheckupReport 拼装 — 主入口数据源.
|
|
4
|
+
// runCheckup() 跑全体 5 维度 + 算 score + 选 top focus + 持久化 history.
|
|
5
|
+
import { checkDimensionUsage, buildUsageSurfaceLines } from './dimension-1-usage.js';
|
|
6
|
+
import { checkDimensionFiles } from './dimension-3-files.js';
|
|
7
|
+
import { checkDimensionContext } from './dimension-4-context.js';
|
|
8
|
+
import { computeHealthScore, selectTopFocus, computeTrend, appendHealthSnapshot, } from './score.js';
|
|
9
|
+
/**
|
|
10
|
+
* 主入口 — 跑一次全 5 维度体检 → CheckupReport
|
|
11
|
+
*/
|
|
12
|
+
export async function runCheckup(deps) {
|
|
13
|
+
const generated_at = new Date().toISOString();
|
|
14
|
+
// 维度 1: 用量 (含 reconciliation)
|
|
15
|
+
const reconciliations = await deps.reconciliationEngine.reconcileAll();
|
|
16
|
+
const usage = checkDimensionUsage({
|
|
17
|
+
store: deps.store,
|
|
18
|
+
reconciliations,
|
|
19
|
+
});
|
|
20
|
+
// 维度 3: 文件 (并行扫)
|
|
21
|
+
const files = await checkDimensionFiles();
|
|
22
|
+
// 维度 4: 上下文
|
|
23
|
+
const context = await checkDimensionContext();
|
|
24
|
+
// 维度 2: 技术债 (Pro 锁, MVP 不做)
|
|
25
|
+
const tech_debt = {
|
|
26
|
+
dimension: 'tech_debt',
|
|
27
|
+
severity: 'pro_locked',
|
|
28
|
+
headline: deps.is_pro ? '即将上线 (2.7.5)' : 'Pro 解锁',
|
|
29
|
+
findings: [],
|
|
30
|
+
pro_locked: !deps.is_pro,
|
|
31
|
+
};
|
|
32
|
+
// 维度 5: 记忆 (Pro 锁, MVP 不做)
|
|
33
|
+
const memory = {
|
|
34
|
+
dimension: 'memory',
|
|
35
|
+
severity: 'pro_locked',
|
|
36
|
+
headline: deps.is_pro ? '即将上线 (2.7.6)' : 'Pro 解锁',
|
|
37
|
+
findings: [],
|
|
38
|
+
pro_locked: !deps.is_pro,
|
|
39
|
+
};
|
|
40
|
+
const dimensions = [usage, files, context, tech_debt, memory];
|
|
41
|
+
const health_score = computeHealthScore(dimensions);
|
|
42
|
+
const health_trend = await computeTrend(health_score).catch(() => undefined);
|
|
43
|
+
const top_focus = selectTopFocus(dimensions);
|
|
44
|
+
const usage_summary_lines = buildUsageSurfaceLines(reconciliations);
|
|
45
|
+
const all_healthy = dimensions.every((d) => d.severity === 'healthy' || d.severity === 'pro_locked' || d.severity === 'no_data');
|
|
46
|
+
const report = {
|
|
47
|
+
generated_at,
|
|
48
|
+
health_score,
|
|
49
|
+
health_trend,
|
|
50
|
+
dimensions,
|
|
51
|
+
top_focus,
|
|
52
|
+
usage_summary_lines,
|
|
53
|
+
all_healthy,
|
|
54
|
+
};
|
|
55
|
+
// 持久化 health snapshot (用于下次 trend)
|
|
56
|
+
if (!deps.skip_persist) {
|
|
57
|
+
await appendHealthSnapshot({ timestamp: generated_at, health_score }).catch(() => {
|
|
58
|
+
// 写失败不阻塞 report
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return report;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 主入口 UX 渲染 — 把 CheckupReport 渲染成 < 300 字的中文文本块.
|
|
65
|
+
* V1.4 乔布斯级打磨 (Eric 真测反馈):
|
|
66
|
+
* - 健康度配形容词 (96 ✨ 优秀 / 67 ⚠ 需关注)
|
|
67
|
+
* - 维度 emoji 一致 + Pro 维度折叠成 1 行不重复
|
|
68
|
+
* - "今日 #1" 用 actionable 文案 (含真数字)
|
|
69
|
+
* - 0 MB 文件正向反馈
|
|
70
|
+
* - action button 收到 2-3 个最关键
|
|
71
|
+
*/
|
|
72
|
+
export function renderMainEntry(report) {
|
|
73
|
+
const lines = [];
|
|
74
|
+
// ── 健康度: score + 形容词 + trend ──
|
|
75
|
+
const overall = scoreLabel(report.health_score);
|
|
76
|
+
const trendStr = formatTrend(report.health_trend);
|
|
77
|
+
lines.push(`🧬 你家 AI · ${report.health_score} 健康度 ${overall.emoji} ${overall.label}${trendStr}`);
|
|
78
|
+
lines.push('━━━━━━━━━━━━━━━━━━━');
|
|
79
|
+
lines.push('');
|
|
80
|
+
// ── Free 维度 (用量 / 文件 / 上下文) ──
|
|
81
|
+
const freeDimensions = report.dimensions.filter((d) => !d.pro_locked);
|
|
82
|
+
for (const dim of freeDimensions) {
|
|
83
|
+
const sevEmoji = severityEmoji(dim.severity);
|
|
84
|
+
const dimLabel = labelOf(dim.dimension);
|
|
85
|
+
lines.push(`${dimLabel} ${sevEmoji} ${dim.headline}`);
|
|
86
|
+
}
|
|
87
|
+
// ── 用量子行 (对账 surface — SkillFM 灵魂位置) ──
|
|
88
|
+
if (report.usage_summary_lines.length > 0) {
|
|
89
|
+
for (const sl of report.usage_summary_lines) {
|
|
90
|
+
lines.push(` · ${sl}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ── Pro 维度 (折成 1 行, 不重复 5 次"Pro 解锁") ──
|
|
94
|
+
const proDimensions = report.dimensions.filter((d) => d.pro_locked);
|
|
95
|
+
if (proDimensions.length > 0) {
|
|
96
|
+
const proLabels = proDimensions.map((d) => labelOf(d.dimension).trim()).join(' + ');
|
|
97
|
+
lines.push(`🔒 ${proLabels} (Pro 解锁深度优化)`);
|
|
98
|
+
}
|
|
99
|
+
lines.push('');
|
|
100
|
+
lines.push('━━━━━━━━━━━━━━━━━━━');
|
|
101
|
+
// ── Today's #1 (or 无问题 fallback) ──
|
|
102
|
+
if (report.all_healthy) {
|
|
103
|
+
lines.push(`✨ 你家 AI 今日高效如初, 继续保持!`);
|
|
104
|
+
}
|
|
105
|
+
else if (report.top_focus) {
|
|
106
|
+
lines.push(`今日重点:`);
|
|
107
|
+
lines.push(` ${report.top_focus.headline}`);
|
|
108
|
+
if (report.top_focus.fix_label) {
|
|
109
|
+
lines.push(` → ${report.top_focus.fix_label}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// ── Action buttons (收到 2-3 个最关键, 不堆 4 个) ──
|
|
113
|
+
lines.push('');
|
|
114
|
+
if (report.top_focus?.fix_free_allowed && report.top_focus.fix_label) {
|
|
115
|
+
// 主 CTA = 修这一个; 副 = 看全部; tertiary = Pro
|
|
116
|
+
lines.push('[🛠 修这一个] [📊 看全部] [✨ Pro]');
|
|
117
|
+
}
|
|
118
|
+
else if (report.all_healthy) {
|
|
119
|
+
lines.push('[📊 看历史] [📤 分享战绩] [✨ Pro]');
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
lines.push('[📊 看全部] [✨ Pro 解锁自动 fix]');
|
|
123
|
+
}
|
|
124
|
+
return lines.join('\n');
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* 健康度 score → 形容词 + emoji (类 iPhone Battery Health 真分级)
|
|
128
|
+
*/
|
|
129
|
+
function scoreLabel(score) {
|
|
130
|
+
if (score >= 95)
|
|
131
|
+
return { emoji: '✨', label: '优秀' };
|
|
132
|
+
if (score >= 85)
|
|
133
|
+
return { emoji: '✅', label: '良好' };
|
|
134
|
+
if (score >= 70)
|
|
135
|
+
return { emoji: '🙂', label: '尚可' };
|
|
136
|
+
if (score >= 50)
|
|
137
|
+
return { emoji: '⚠️', label: '需关注' };
|
|
138
|
+
return { emoji: '🔴', label: '需立刻处理' };
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Trend 文案: ↑8 / ↓11 / 无变化
|
|
142
|
+
*/
|
|
143
|
+
function formatTrend(trend) {
|
|
144
|
+
if (trend == null)
|
|
145
|
+
return '';
|
|
146
|
+
if (trend === 0)
|
|
147
|
+
return ' (vs 上次, 持平)';
|
|
148
|
+
if (trend > 0)
|
|
149
|
+
return ` (vs 上次, ↑${trend})`;
|
|
150
|
+
return ` (vs 上次, ↓${-trend})`;
|
|
151
|
+
}
|
|
152
|
+
function severityEmoji(s) {
|
|
153
|
+
switch (s) {
|
|
154
|
+
case 'critical': return '🔴';
|
|
155
|
+
case 'warning': return '🟠';
|
|
156
|
+
case 'info': return '🟡';
|
|
157
|
+
case 'healthy': return '✅';
|
|
158
|
+
case 'pro_locked': return '';
|
|
159
|
+
case 'no_data': return '❓';
|
|
160
|
+
default: return '';
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function labelOf(dim) {
|
|
164
|
+
switch (dim) {
|
|
165
|
+
case 'usage': return '💰 用量 ';
|
|
166
|
+
case 'tech_debt': return '🐛 技术债 ';
|
|
167
|
+
case 'files': return '📦 文件 ';
|
|
168
|
+
case 'context': return '📁 上下文 ';
|
|
169
|
+
case 'memory': return '🧠 记忆 ';
|
|
170
|
+
default: return dim;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/checkup/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { DimensionStatus, Finding, HealthSnapshot } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 算总 score (基于所有 dimension 的 findings)
|
|
4
|
+
*/
|
|
5
|
+
export declare function computeHealthScore(dimensions: DimensionStatus[]): number;
|
|
6
|
+
/**
|
|
7
|
+
* 选 "今日 #1" — 最该 surface 的 1 个 finding (PRD §3.2 治信息过载)
|
|
8
|
+
*
|
|
9
|
+
* 选择策略 (按优先级):
|
|
10
|
+
* 1. 最严重 critical (score_deduction 最高)
|
|
11
|
+
* 2. 如果有 fix_free_allowed=true 的 critical, 优先选可执行的 (用户能立刻动作)
|
|
12
|
+
* 3. 否则取所有 findings 中 score_deduction 最高的
|
|
13
|
+
*/
|
|
14
|
+
export declare function selectTopFocus(dimensions: DimensionStatus[]): Finding | null;
|
|
15
|
+
/**
|
|
16
|
+
* 加载健康度历史 (用于 trend 计算)
|
|
17
|
+
*/
|
|
18
|
+
export declare function loadHealthHistory(filePath?: string): Promise<HealthSnapshot[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Append 一条健康度 snapshot
|
|
21
|
+
*/
|
|
22
|
+
export declare function appendHealthSnapshot(snap: HealthSnapshot, filePath?: string): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* 算 trend (vs 上次 snapshot)
|
|
25
|
+
*/
|
|
26
|
+
export declare function computeTrend(currentScore: number, historyPath?: string): Promise<number | undefined>;
|
|
27
|
+
//# sourceMappingURL=score.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score.d.ts","sourceRoot":"","sources":["../../src/checkup/score.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAiB,eAAe,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAI1F;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,eAAe,EAAE,GAAG,MAAM,CASxE;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,eAAe,EAAE,GAAG,OAAO,GAAG,IAAI,CAwB5E;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,GAAE,MAA4B,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAczG;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,cAAc,EACpB,QAAQ,GAAE,MAA4B,GACrC,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAK1G"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/checkup/score.ts
|
|
2
|
+
//
|
|
3
|
+
// 健康度公式 (PRD V1.3 §7, Eric 拍板):
|
|
4
|
+
// 用量 40% / 上下文 25% / 文件 15% / 技术债 10% / 记忆 10%
|
|
5
|
+
//
|
|
6
|
+
// 算法: score = max(0, 100 - Σ (weight × dimension_deduction_normalized))
|
|
7
|
+
// 但因 finding 有 score_deduction 真值, 简化为:
|
|
8
|
+
// score = max(0, 100 - Σ findings[].score_deduction)
|
|
9
|
+
//
|
|
10
|
+
// Free 用户: 上限 100 (Eric 决策 #6, 不区分不 cripple)
|
|
11
|
+
// Pro 维度 (技术债/记忆) 在 Free 用户的 deduction = 0 (锁了不算分)
|
|
12
|
+
import * as fs from 'node:fs';
|
|
13
|
+
import * as path from 'node:path';
|
|
14
|
+
import { homedir } from 'node:os';
|
|
15
|
+
const HEALTH_HISTORY_PATH = path.join(homedir(), '.skillfm', 'health-history.jsonl');
|
|
16
|
+
/**
|
|
17
|
+
* 算总 score (基于所有 dimension 的 findings)
|
|
18
|
+
*/
|
|
19
|
+
export function computeHealthScore(dimensions) {
|
|
20
|
+
let totalDeduction = 0;
|
|
21
|
+
for (const dim of dimensions) {
|
|
22
|
+
if (dim.pro_locked)
|
|
23
|
+
continue; // Free 用户 Pro 维度不算分
|
|
24
|
+
for (const finding of dim.findings) {
|
|
25
|
+
totalDeduction += finding.score_deduction;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return Math.max(0, Math.min(100, 100 - totalDeduction));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 选 "今日 #1" — 最该 surface 的 1 个 finding (PRD §3.2 治信息过载)
|
|
32
|
+
*
|
|
33
|
+
* 选择策略 (按优先级):
|
|
34
|
+
* 1. 最严重 critical (score_deduction 最高)
|
|
35
|
+
* 2. 如果有 fix_free_allowed=true 的 critical, 优先选可执行的 (用户能立刻动作)
|
|
36
|
+
* 3. 否则取所有 findings 中 score_deduction 最高的
|
|
37
|
+
*/
|
|
38
|
+
export function selectTopFocus(dimensions) {
|
|
39
|
+
const allFindings = [];
|
|
40
|
+
for (const dim of dimensions) {
|
|
41
|
+
if (dim.pro_locked)
|
|
42
|
+
continue;
|
|
43
|
+
allFindings.push(...dim.findings);
|
|
44
|
+
}
|
|
45
|
+
if (allFindings.length === 0)
|
|
46
|
+
return null;
|
|
47
|
+
// 优先 critical + fix_free_allowed
|
|
48
|
+
const critFreeFix = allFindings.filter((f) => f.severity === 'critical' && f.fix_free_allowed);
|
|
49
|
+
if (critFreeFix.length > 0) {
|
|
50
|
+
return critFreeFix.sort((a, b) => b.score_deduction - a.score_deduction)[0];
|
|
51
|
+
}
|
|
52
|
+
// 其次 critical
|
|
53
|
+
const crit = allFindings.filter((f) => f.severity === 'critical');
|
|
54
|
+
if (crit.length > 0) {
|
|
55
|
+
return crit.sort((a, b) => b.score_deduction - a.score_deduction)[0];
|
|
56
|
+
}
|
|
57
|
+
// 最后按 deduction 排序
|
|
58
|
+
return allFindings.sort((a, b) => b.score_deduction - a.score_deduction)[0];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 加载健康度历史 (用于 trend 计算)
|
|
62
|
+
*/
|
|
63
|
+
export async function loadHealthHistory(filePath = HEALTH_HISTORY_PATH) {
|
|
64
|
+
if (!fs.existsSync(filePath))
|
|
65
|
+
return [];
|
|
66
|
+
const text = await fs.promises.readFile(filePath, 'utf-8');
|
|
67
|
+
const out = [];
|
|
68
|
+
for (const line of text.split('\n')) {
|
|
69
|
+
const t = line.trim();
|
|
70
|
+
if (!t.startsWith('{'))
|
|
71
|
+
continue;
|
|
72
|
+
try {
|
|
73
|
+
out.push(JSON.parse(t));
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// skip
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return out.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Append 一条健康度 snapshot
|
|
83
|
+
*/
|
|
84
|
+
export async function appendHealthSnapshot(snap, filePath = HEALTH_HISTORY_PATH) {
|
|
85
|
+
const dir = path.dirname(filePath);
|
|
86
|
+
if (!fs.existsSync(dir)) {
|
|
87
|
+
await fs.promises.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
88
|
+
}
|
|
89
|
+
await fs.promises.appendFile(filePath, JSON.stringify(snap) + '\n', { mode: 0o600 });
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 算 trend (vs 上次 snapshot)
|
|
93
|
+
*/
|
|
94
|
+
export async function computeTrend(currentScore, historyPath) {
|
|
95
|
+
const history = await loadHealthHistory(historyPath);
|
|
96
|
+
if (history.length === 0)
|
|
97
|
+
return undefined;
|
|
98
|
+
const last = history[history.length - 1];
|
|
99
|
+
return currentScore - last.health_score;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=score.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/checkup/score.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export type DimensionId = 'usage' | 'tech_debt' | 'files' | 'context' | 'memory';
|
|
2
|
+
export type Severity = 'critical' | 'warning' | 'info' | 'healthy' | 'pro_locked' | 'no_data';
|
|
3
|
+
/**
|
|
4
|
+
* 一个 deduction = 一项发现的问题 (用于 score 计算 + UX surface)
|
|
5
|
+
*/
|
|
6
|
+
export interface Finding {
|
|
7
|
+
/** 短描述 (主入口 surface 行用) */
|
|
8
|
+
headline: string;
|
|
9
|
+
/** 严重度 */
|
|
10
|
+
severity: Severity;
|
|
11
|
+
/** 扣分 (0-30) */
|
|
12
|
+
score_deduction: number;
|
|
13
|
+
/** 一键 fix 文案 (可选, 主入口 [修这一个] 时用) */
|
|
14
|
+
fix_label?: string;
|
|
15
|
+
/** 是否 Free 用户可执行 fix */
|
|
16
|
+
fix_free_allowed?: boolean;
|
|
17
|
+
/** 真省 (如果 fix 后, 估算月省 token / ¥) */
|
|
18
|
+
estimated_savings?: {
|
|
19
|
+
tokens?: number;
|
|
20
|
+
cny?: number;
|
|
21
|
+
description?: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 单个维度的体检结果
|
|
26
|
+
*/
|
|
27
|
+
export interface DimensionStatus {
|
|
28
|
+
dimension: DimensionId;
|
|
29
|
+
/** 维度总 severity (取 findings 中最高) */
|
|
30
|
+
severity: Severity;
|
|
31
|
+
/** 维度 1 行 headline (主入口 surface) */
|
|
32
|
+
headline: string;
|
|
33
|
+
/** 该维度所有 findings */
|
|
34
|
+
findings: Finding[];
|
|
35
|
+
/** Pro 锁标 */
|
|
36
|
+
pro_locked: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Checkup 完整报告 — 主入口数据源
|
|
40
|
+
*/
|
|
41
|
+
export interface CheckupReport {
|
|
42
|
+
generated_at: string;
|
|
43
|
+
/** 整体健康度 0-100 */
|
|
44
|
+
health_score: number;
|
|
45
|
+
/** vs 上次 score 的变化 (+/- 数, 用于 trend "↑ 28") */
|
|
46
|
+
health_trend?: number;
|
|
47
|
+
/** 5 维度状态 */
|
|
48
|
+
dimensions: DimensionStatus[];
|
|
49
|
+
/** "今日 #1" — 最该看的 1 件事 (treats 信息过载, PRD §3.2) */
|
|
50
|
+
top_focus: Finding | null;
|
|
51
|
+
/** 主入口的"💰 用量"那一行 (来自 reconciliation summary) */
|
|
52
|
+
usage_summary_lines: string[];
|
|
53
|
+
/** 是否所有维度都 healthy → fallback UX */
|
|
54
|
+
all_healthy: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* 健康度历史 snapshot (持久化在 ~/.skillfm/health-history.jsonl)
|
|
58
|
+
* 用于 trend 计算 + Daily push 文案
|
|
59
|
+
*/
|
|
60
|
+
export interface HealthSnapshot {
|
|
61
|
+
timestamp: string;
|
|
62
|
+
health_score: number;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/checkup/types.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,WAAW,GACX,OAAO,GACP,SAAS,GACT,QAAQ,CAAC;AAEb,MAAM,MAAM,QAAQ,GAChB,UAAU,GACV,SAAS,GACT,MAAM,GACN,SAAS,GACT,YAAY,GACZ,SAAS,CAAC;AAEd;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU;IACV,QAAQ,EAAE,QAAQ,CAAC;IACnB,gBAAgB;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oCAAoC;IACpC,iBAAiB,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7E;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,WAAW,CAAC;IACvB,oCAAoC;IACpC,QAAQ,EAAE,QAAQ,CAAC;IACnB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,aAAa;IACb,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa;IACb,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,kDAAkD;IAClD,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,iDAAiD;IACjD,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,oCAAoC;IACpC,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB"}
|