@skillfm/local 2.7.2 → 2.7.4

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 (126) hide show
  1. package/dist/checkup/daily-push.d.ts +29 -0
  2. package/dist/checkup/daily-push.d.ts.map +1 -0
  3. package/dist/checkup/daily-push.js +86 -0
  4. package/dist/checkup/daily-push.js.map +1 -0
  5. package/dist/checkup/dimension-1-usage.d.ts +22 -0
  6. package/dist/checkup/dimension-1-usage.d.ts.map +1 -0
  7. package/dist/checkup/dimension-1-usage.js +115 -0
  8. package/dist/checkup/dimension-1-usage.js.map +1 -0
  9. package/dist/checkup/dimension-3-files.d.ts +23 -0
  10. package/dist/checkup/dimension-3-files.d.ts.map +1 -0
  11. package/dist/checkup/dimension-3-files.js +165 -0
  12. package/dist/checkup/dimension-3-files.js.map +1 -0
  13. package/dist/checkup/dimension-4-context.d.ts +18 -0
  14. package/dist/checkup/dimension-4-context.d.ts.map +1 -0
  15. package/dist/checkup/dimension-4-context.js +177 -0
  16. package/dist/checkup/dimension-4-context.js.map +1 -0
  17. package/dist/checkup/index.d.ts +11 -0
  18. package/dist/checkup/index.d.ts.map +1 -0
  19. package/dist/checkup/index.js +10 -0
  20. package/dist/checkup/index.js.map +1 -0
  21. package/dist/checkup/report.d.ts +21 -0
  22. package/dist/checkup/report.d.ts.map +1 -0
  23. package/dist/checkup/report.js +133 -0
  24. package/dist/checkup/report.js.map +1 -0
  25. package/dist/checkup/score.d.ts +27 -0
  26. package/dist/checkup/score.d.ts.map +1 -0
  27. package/dist/checkup/score.js +101 -0
  28. package/dist/checkup/score.js.map +1 -0
  29. package/dist/checkup/types.d.ts +64 -0
  30. package/dist/checkup/types.d.ts.map +1 -0
  31. package/dist/checkup/types.js +5 -0
  32. package/dist/checkup/types.js.map +1 -0
  33. package/dist/connectors/anthropic.d.ts.map +1 -1
  34. package/dist/connectors/anthropic.js +3 -0
  35. package/dist/connectors/anthropic.js.map +1 -1
  36. package/dist/guard/bin.js +0 -0
  37. package/dist/index.js +4 -2
  38. package/dist/index.js.map +1 -1
  39. package/dist/mcp/index.d.ts.map +1 -1
  40. package/dist/mcp/index.js +27 -0
  41. package/dist/mcp/index.js.map +1 -1
  42. package/dist/mcp/tools/checkup.d.ts +21 -0
  43. package/dist/mcp/tools/checkup.d.ts.map +1 -0
  44. package/dist/mcp/tools/checkup.js +35 -0
  45. package/dist/mcp/tools/checkup.js.map +1 -0
  46. package/dist/mcp/tools/explain-provider-key.d.ts.map +1 -1
  47. package/dist/mcp/tools/explain-provider-key.js +15 -13
  48. package/dist/mcp/tools/explain-provider-key.js.map +1 -1
  49. package/dist/mcp/tools/index.d.ts +6 -0
  50. package/dist/mcp/tools/index.d.ts.map +1 -1
  51. package/dist/mcp/tools/index.js +56 -4
  52. package/dist/mcp/tools/index.js.map +1 -1
  53. package/dist/mcp/tools/setup-gateway.d.ts +16 -0
  54. package/dist/mcp/tools/setup-gateway.d.ts.map +1 -0
  55. package/dist/mcp/tools/setup-gateway.js +79 -0
  56. package/dist/mcp/tools/setup-gateway.js.map +1 -0
  57. package/dist/mcp/tools/show-my-usage.d.ts +26 -0
  58. package/dist/mcp/tools/show-my-usage.d.ts.map +1 -0
  59. package/dist/mcp/tools/show-my-usage.js +68 -0
  60. package/dist/mcp/tools/show-my-usage.js.map +1 -0
  61. package/dist/mcp-stdio/bin.js +0 -0
  62. package/dist/reconciliation/engine.d.ts +30 -0
  63. package/dist/reconciliation/engine.d.ts.map +1 -0
  64. package/dist/reconciliation/engine.js +62 -0
  65. package/dist/reconciliation/engine.js.map +1 -0
  66. package/dist/reconciliation/index.d.ts +8 -0
  67. package/dist/reconciliation/index.d.ts.map +1 -0
  68. package/dist/reconciliation/index.js +8 -0
  69. package/dist/reconciliation/index.js.map +1 -0
  70. package/dist/reconciliation/l1-reconciler.d.ts +29 -0
  71. package/dist/reconciliation/l1-reconciler.d.ts.map +1 -0
  72. package/dist/reconciliation/l1-reconciler.js +144 -0
  73. package/dist/reconciliation/l1-reconciler.js.map +1 -0
  74. package/dist/reconciliation/l2-reconciler.d.ts +21 -0
  75. package/dist/reconciliation/l2-reconciler.d.ts.map +1 -0
  76. package/dist/reconciliation/l2-reconciler.js +241 -0
  77. package/dist/reconciliation/l2-reconciler.js.map +1 -0
  78. package/dist/reconciliation/types.d.ts +49 -0
  79. package/dist/reconciliation/types.d.ts.map +1 -0
  80. package/dist/reconciliation/types.js +9 -0
  81. package/dist/reconciliation/types.js.map +1 -0
  82. package/dist/save-token/e1-router.d.ts +7 -0
  83. package/dist/save-token/e1-router.d.ts.map +1 -0
  84. package/dist/save-token/e1-router.js +112 -0
  85. package/dist/save-token/e1-router.js.map +1 -0
  86. package/dist/save-token/e2-cache.d.ts +7 -0
  87. package/dist/save-token/e2-cache.d.ts.map +1 -0
  88. package/dist/save-token/e2-cache.js +128 -0
  89. package/dist/save-token/e2-cache.js.map +1 -0
  90. package/dist/save-token/e3-batch.d.ts +7 -0
  91. package/dist/save-token/e3-batch.d.ts.map +1 -0
  92. package/dist/save-token/e3-batch.js +80 -0
  93. package/dist/save-token/e3-batch.js.map +1 -0
  94. package/dist/save-token/gateway-setup.d.ts +27 -0
  95. package/dist/save-token/gateway-setup.d.ts.map +1 -0
  96. package/dist/save-token/gateway-setup.js +200 -0
  97. package/dist/save-token/gateway-setup.js.map +1 -0
  98. package/dist/save-token/index.d.ts +13 -0
  99. package/dist/save-token/index.d.ts.map +1 -0
  100. package/dist/save-token/index.js +23 -0
  101. package/dist/save-token/index.js.map +1 -0
  102. package/dist/save-token/types.d.ts +46 -0
  103. package/dist/save-token/types.d.ts.map +1 -0
  104. package/dist/save-token/types.js +5 -0
  105. package/dist/save-token/types.js.map +1 -0
  106. package/dist/usage-local/index.d.ts +32 -0
  107. package/dist/usage-local/index.d.ts.map +1 -0
  108. package/dist/usage-local/index.js +32 -0
  109. package/dist/usage-local/index.js.map +1 -0
  110. package/dist/usage-local/model-pricing.d.ts +38 -0
  111. package/dist/usage-local/model-pricing.d.ts.map +1 -0
  112. package/dist/usage-local/model-pricing.js +230 -0
  113. package/dist/usage-local/model-pricing.js.map +1 -0
  114. package/dist/usage-local/openclaw-watcher.d.ts +35 -0
  115. package/dist/usage-local/openclaw-watcher.d.ts.map +1 -0
  116. package/dist/usage-local/openclaw-watcher.js +190 -0
  117. package/dist/usage-local/openclaw-watcher.js.map +1 -0
  118. package/dist/usage-local/store.d.ts +50 -0
  119. package/dist/usage-local/store.d.ts.map +1 -0
  120. package/dist/usage-local/store.js +201 -0
  121. package/dist/usage-local/store.js.map +1 -0
  122. package/dist/usage-local/types.d.ts +94 -0
  123. package/dist/usage-local/types.d.ts.map +1 -0
  124. package/dist/usage-local/types.js +6 -0
  125. package/dist/usage-local/types.js.map +1 -0
  126. package/package.json +2 -2
@@ -0,0 +1,201 @@
1
+ // sdk/skillfm-local/src/usage-local/store.ts
2
+ //
3
+ // LocalUsageStore — 持久化 + 时序聚合 query.
4
+ // 第一版用 in-memory + JSON 文件持久化 (~/.skillfm/usage-local.json),
5
+ // 0 新依赖. 后续如果数据量大 (>10k records) 再换 sqlite (better-sqlite3).
6
+ //
7
+ // 文件格式: append-only JSONL (每行一个 LocalUsageRecord), 高效 + 可恢复.
8
+ // dedup 靠 record.id (基于 sessionId+timestamp+runId 的稳定 hash).
9
+ import * as fs from 'node:fs';
10
+ import * as path from 'node:path';
11
+ import { homedir } from 'node:os';
12
+ const DEFAULT_STORE_PATH = path.join(homedir(), '.skillfm', 'usage-local.jsonl');
13
+ /**
14
+ * Local usage store
15
+ * - in-memory Map (id → record) for dedup + 快速 query
16
+ * - jsonl 持久化 (append-only, 每条 record 一行)
17
+ * - load() 从 jsonl 重建 in-memory state
18
+ */
19
+ export class LocalUsageStore {
20
+ records = new Map();
21
+ filePath;
22
+ dirty = false;
23
+ constructor(opts = {}) {
24
+ this.filePath = opts.filePath ?? DEFAULT_STORE_PATH;
25
+ }
26
+ /** 启动时从文件 load */
27
+ async load() {
28
+ if (!fs.existsSync(this.filePath)) {
29
+ // 确保目录存在
30
+ const dir = path.dirname(this.filePath);
31
+ if (!fs.existsSync(dir)) {
32
+ await fs.promises.mkdir(dir, { recursive: true, mode: 0o700 });
33
+ }
34
+ return;
35
+ }
36
+ const text = await fs.promises.readFile(this.filePath, 'utf-8');
37
+ for (const line of text.split('\n')) {
38
+ const trimmed = line.trim();
39
+ if (!trimmed || !trimmed.startsWith('{'))
40
+ continue;
41
+ try {
42
+ const r = JSON.parse(trimmed);
43
+ if (r.id)
44
+ this.records.set(r.id, r);
45
+ }
46
+ catch {
47
+ // skip malformed
48
+ }
49
+ }
50
+ }
51
+ /** 批量 append (dedup by id), 写文件 */
52
+ async appendBatch(batch) {
53
+ if (batch.length === 0)
54
+ return 0;
55
+ const newRecords = [];
56
+ for (const r of batch) {
57
+ if (!this.records.has(r.id)) {
58
+ this.records.set(r.id, r);
59
+ newRecords.push(r);
60
+ }
61
+ }
62
+ if (newRecords.length === 0)
63
+ return 0;
64
+ // 确保目录存在 (defensive)
65
+ const dir = path.dirname(this.filePath);
66
+ if (!fs.existsSync(dir)) {
67
+ await fs.promises.mkdir(dir, { recursive: true, mode: 0o700 });
68
+ }
69
+ const lines = newRecords.map((r) => JSON.stringify(r)).join('\n') + '\n';
70
+ await fs.promises.appendFile(this.filePath, lines, { mode: 0o600 });
71
+ return newRecords.length;
72
+ }
73
+ /** 当前所有 records 数 */
74
+ size() {
75
+ return this.records.size;
76
+ }
77
+ /** Query records (基础筛选) */
78
+ query(q = {}) {
79
+ const startMs = q.start ? Date.parse(q.start) : 0;
80
+ const endMs = q.end ? Date.parse(q.end) : Number.MAX_SAFE_INTEGER;
81
+ const providerSet = q.providers ? new Set(q.providers.map((p) => p.toLowerCase())) : null;
82
+ const agentSet = q.agents ? new Set(q.agents) : null;
83
+ const out = [];
84
+ for (const r of this.records.values()) {
85
+ const ts = Date.parse(r.timestamp);
86
+ if (ts < startMs || ts >= endMs)
87
+ continue;
88
+ if (providerSet && !providerSet.has(r.provider.toLowerCase()))
89
+ continue;
90
+ if (agentSet && !agentSet.has(r.agent_harness))
91
+ continue;
92
+ out.push(r);
93
+ }
94
+ return out.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
95
+ }
96
+ /** 时间窗口聚合 (总数) */
97
+ aggregate(q = {}) {
98
+ const records = this.query(q);
99
+ return this.aggregateRecords(records, q.start ?? '', q.end ?? '');
100
+ }
101
+ /** 按 provider 聚合 */
102
+ aggregateByProvider(q = {}) {
103
+ const records = this.query(q);
104
+ const groups = new Map();
105
+ for (const r of records) {
106
+ const key = r.provider;
107
+ const list = groups.get(key) ?? [];
108
+ list.push(r);
109
+ groups.set(key, list);
110
+ }
111
+ return Array.from(groups.entries()).map(([provider, rs]) => ({
112
+ provider,
113
+ ...this.aggregateRecords(rs, q.start ?? '', q.end ?? ''),
114
+ }));
115
+ }
116
+ /** 按 agent harness 聚合 */
117
+ aggregateByAgent(q = {}) {
118
+ const records = this.query(q);
119
+ const groups = new Map();
120
+ for (const r of records) {
121
+ const list = groups.get(r.agent_harness) ?? [];
122
+ list.push(r);
123
+ groups.set(r.agent_harness, list);
124
+ }
125
+ return Array.from(groups.entries()).map(([agent_harness, rs]) => ({
126
+ agent_harness,
127
+ ...this.aggregateRecords(rs, q.start ?? '', q.end ?? ''),
128
+ }));
129
+ }
130
+ /** 按 (provider, model) 聚合 */
131
+ aggregateByModel(q = {}) {
132
+ const records = this.query(q);
133
+ const groups = new Map();
134
+ for (const r of records) {
135
+ const key = `${r.provider}/${r.model_id}`;
136
+ const list = groups.get(key) ?? [];
137
+ list.push(r);
138
+ groups.set(key, list);
139
+ }
140
+ return Array.from(groups.entries()).map(([key, rs]) => {
141
+ const [provider, ...rest] = key.split('/');
142
+ const model_id = rest.join('/');
143
+ return {
144
+ provider: provider,
145
+ model_id,
146
+ ...this.aggregateRecords(rs, q.start ?? '', q.end ?? ''),
147
+ };
148
+ });
149
+ }
150
+ /** Helper: 聚合 records 列表 */
151
+ aggregateRecords(records, start, end) {
152
+ let input = 0, output = 0, cacheRead = 0, cacheWrite = 0, costUsd = 0, costCny = 0;
153
+ for (const r of records) {
154
+ input += r.input_tokens;
155
+ output += r.output_tokens;
156
+ cacheRead += r.cache_read_tokens;
157
+ cacheWrite += r.cache_write_tokens;
158
+ costUsd += r.estimated_cost_usd;
159
+ costCny += r.estimated_cost_cny;
160
+ }
161
+ return {
162
+ window_start: start,
163
+ window_end: end,
164
+ input_tokens: input,
165
+ output_tokens: output,
166
+ cache_read_tokens: cacheRead,
167
+ cache_write_tokens: cacheWrite,
168
+ total_cost_usd: costUsd,
169
+ total_cost_cny: costCny,
170
+ call_count: records.length,
171
+ };
172
+ }
173
+ /** 清空 (测试用 / 用户主动清) */
174
+ async clear() {
175
+ this.records.clear();
176
+ if (fs.existsSync(this.filePath)) {
177
+ await fs.promises.unlink(this.filePath);
178
+ }
179
+ }
180
+ }
181
+ /**
182
+ * 时间窗口快捷:今日 / 本周 / 本月
183
+ */
184
+ export function timeWindow(period) {
185
+ const now = new Date();
186
+ if (period === 'all')
187
+ return {};
188
+ if (period === 'today') {
189
+ const start = new Date(now.getFullYear(), now.getMonth(), now.getDate());
190
+ return { start: start.toISOString() };
191
+ }
192
+ if (period === 'week') {
193
+ const start = new Date(now);
194
+ start.setDate(now.getDate() - 7);
195
+ return { start: start.toISOString() };
196
+ }
197
+ // month
198
+ const start = new Date(now.getFullYear(), now.getMonth(), 1);
199
+ return { start: start.toISOString() };
200
+ }
201
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/usage-local/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * 一次 LLM 调用的真原子记录 (来自 agent trajectory)
3
+ * 跨 agent / 跨 provider 统一 schema
4
+ */
5
+ export interface LocalUsageRecord {
6
+ /** 唯一 ID — 用于去重 (基于 agent+session+turn 哈希) */
7
+ id: string;
8
+ /** ISO 8601 时间戳 */
9
+ timestamp: string;
10
+ /** Agent harness 类型 — openclaw / claude-code / cursor / codex / aider / other */
11
+ agent_harness: AgentHarness;
12
+ /** Agent session ID (各 harness 自己的) */
13
+ session_id: string;
14
+ /** Provider — anthropic / openai / deepseek / doubao / qwen / kimi / minimax / ollama / other */
15
+ provider: string;
16
+ /** Model ID (各 provider 自己的, 如 'claude-sonnet-4-6' / 'gpt-4o' / 'MiniMax-M2.7') */
17
+ model_id: string;
18
+ /** 输入 token (uncached) */
19
+ input_tokens: number;
20
+ /** 输出 token */
21
+ output_tokens: number;
22
+ /** Cache 读 token (cache hit, 通常便宜 10x) */
23
+ cache_read_tokens: number;
24
+ /** Cache 写 token (创建 cache, Anthropic 收 1.25x 价) */
25
+ cache_write_tokens: number;
26
+ /** 总 token (= input + output, 不含 cache_read) — 兼容历史字段 */
27
+ total_tokens: number;
28
+ /** 估算成本 USD (基于 model-pricing.ts 真价目) */
29
+ estimated_cost_usd: number;
30
+ /** 估算成本 CNY (= USD × 7.3) */
31
+ estimated_cost_cny: number;
32
+ /** trajectory 文件路径 (用于 debug / dedup) */
33
+ source_file: string;
34
+ }
35
+ export type AgentHarness = 'openclaw' | 'claude-code' | 'cursor' | 'codex' | 'aider' | 'continue' | 'other';
36
+ /**
37
+ * 时序聚合查询结果 (按 day / week / month 分组)
38
+ */
39
+ export interface UsageAggregation {
40
+ /** 时间窗口 ISO 8601 起始 */
41
+ window_start: string;
42
+ /** 时间窗口 ISO 8601 结束 */
43
+ window_end: string;
44
+ /** 总 input token */
45
+ input_tokens: number;
46
+ /** 总 output token */
47
+ output_tokens: number;
48
+ /** 总 cache read */
49
+ cache_read_tokens: number;
50
+ /** 总 cache write */
51
+ cache_write_tokens: number;
52
+ /** 估算总成本 USD */
53
+ total_cost_usd: number;
54
+ /** 估算总成本 CNY */
55
+ total_cost_cny: number;
56
+ /** 调用次数 */
57
+ call_count: number;
58
+ }
59
+ /**
60
+ * 按 provider 分组的聚合
61
+ */
62
+ export interface UsageByProvider extends UsageAggregation {
63
+ provider: string;
64
+ }
65
+ /**
66
+ * 按 agent harness 分组的聚合
67
+ */
68
+ export interface UsageByAgent extends UsageAggregation {
69
+ agent_harness: AgentHarness;
70
+ }
71
+ /**
72
+ * 按 model 分组的聚合
73
+ */
74
+ export interface UsageByModel extends UsageAggregation {
75
+ provider: string;
76
+ model_id: string;
77
+ }
78
+ /**
79
+ * Watcher 配置
80
+ */
81
+ export interface WatcherConfig {
82
+ /** 监听的 trajectory 目录 (各 harness 路径) */
83
+ watch_paths: WatchPath[];
84
+ /** sqlite db 文件路径 (默认 ~/.skillfm/usage-local.db) */
85
+ db_path: string;
86
+ /** 是否启用 verbose 日志 */
87
+ verbose: boolean;
88
+ }
89
+ export interface WatchPath {
90
+ agent_harness: AgentHarness;
91
+ /** glob 路径 (例: `~/.openclaw/agents/<id>/sessions/<sess>.trajectory.jsonl`) */
92
+ glob: string;
93
+ }
94
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/usage-local/types.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,aAAa,EAAE,YAAY,CAAC;IAC5B,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,iGAAiG;IACjG,QAAQ,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oDAAoD;IACpD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,6BAA6B;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,YAAY,GACpB,UAAU,GACV,aAAa,GACb,QAAQ,GACR,OAAO,GACP,OAAO,GACP,UAAU,GACV,OAAO,CAAC;AAEZ;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,aAAa,EAAE,YAAY,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,YAAY,CAAC;IAC5B,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;CACd"}
@@ -0,0 +1,6 @@
1
+ // sdk/skillfm-local/src/usage-local/types.ts
2
+ //
3
+ // L0 layer types — 本地 agent trajectory 聚合的数据 schema.
4
+ // 跨 agent (OpenClaw / Claude Code / Cursor) 统一表达每次 LLM 调用的真用量。
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/usage-local/types.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,EAAE;AACF,qDAAqD;AACrD,+DAA+D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillfm/local",
3
- "version": "2.7.2",
3
+ "version": "2.7.4",
4
4
  "description": "SkillFM local — single npm package for the SkillFM platform on user nodes. Subcommand router exposes (1) Beacon MCP stdio server (cost-optimizer for any agent; merged in from @skillfm/beacon-mcp on 2026-05-01), (2) skill runtime (BYOK Playwright / brain reverse-tunnel), (3) sidecar HTTP proxy + OAuth 2.1 device-flow activation. Writes ~/.skillfm/local.json for service discovery.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -53,7 +53,7 @@
53
53
  "typecheck": "tsc --noEmit",
54
54
  "start": "node dist/index.js start",
55
55
  "prepublishOnly": "npm run build && bash scripts/verify-no-bare-workspace-imports.sh dist",
56
- "test": "tsx --test src/harness/detector.test.ts src/harness/priming.test.ts src/harness/writers.test.ts src/guard/state.test.ts src/soul.test.ts src/soul-security.test.ts src/harness/kernels/registry.test.ts src/harness/kernels/deny-pipeline.test.ts src/mcp-output/builder.test.ts src/mcp-output/deny-review.test.ts src/mcp-output/integration.test.ts src/skill-md/template.test.ts src/skill-md/writer.test.ts src/mcp-stdio/smoke.test.ts src/mcp-stdio/render-flow.contract.test.ts src/mcp-stdio/render-aha.test.ts src/mcp-stdio/sse-progress-client.test.ts src/mcp-stdio/parse-tolerant-json.test.ts src/self-upgrade.test.ts src/skill-tunnel/local-bridge.test.ts src/skill-tunnel/client.test.ts src/skill-runner/discovery.test.ts src/skill-installer/index.test.ts src/_dist-no-external-contracts.test.ts src/mcp/server-boot.test.ts src/connectors/connectors.test.ts src/asset-connectors/asset-connectors.test.ts src/saas-connectors/saas-connectors.test.ts src/router/router.test.ts src/vault/vault.test.ts src/scheduler/scheduler.test.ts src/_signers/signers.test.ts src/memory/memory.test.ts src/mcp/tools/memory-tools.test.ts",
56
+ "test": "tsx --test src/harness/detector.test.ts src/harness/priming.test.ts src/harness/writers.test.ts src/guard/state.test.ts src/soul.test.ts src/soul-security.test.ts src/harness/kernels/registry.test.ts src/harness/kernels/deny-pipeline.test.ts src/mcp-output/builder.test.ts src/mcp-output/deny-review.test.ts src/mcp-output/integration.test.ts src/skill-md/template.test.ts src/skill-md/writer.test.ts src/mcp-stdio/smoke.test.ts src/mcp-stdio/render-flow.contract.test.ts src/mcp-stdio/render-aha.test.ts src/mcp-stdio/sse-progress-client.test.ts src/mcp-stdio/parse-tolerant-json.test.ts src/self-upgrade.test.ts src/skill-tunnel/local-bridge.test.ts src/skill-tunnel/client.test.ts src/skill-runner/discovery.test.ts src/skill-installer/index.test.ts src/_dist-no-external-contracts.test.ts src/mcp/server-boot.test.ts src/connectors/connectors.test.ts src/asset-connectors/asset-connectors.test.ts src/saas-connectors/saas-connectors.test.ts src/router/router.test.ts src/vault/vault.test.ts src/scheduler/scheduler.test.ts src/_signers/signers.test.ts src/memory/memory.test.ts src/mcp/tools/memory-tools.test.ts src/checkup/checkup.test.ts",
57
57
  "test:acceptance": "npm run build && bash scripts/acceptance-matrix.sh",
58
58
  "postpublish": "curl -sS -m 10 -X PUT 'https://registry.npmmirror.com/-/package/@skillfm/local/syncs?sync_upstream=true' > /dev/null && echo '✓ npmmirror sync triggered' || echo '⚠ npmmirror sync failed (非阻塞,可手动触发)'"
59
59
  },