vibeusage 0.2.23 → 0.3.0

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.
@@ -0,0 +1,33 @@
1
+ export const REQUIRED_COPY_COLUMNS: string[];
2
+
3
+ export function parseCsvRows(raw: string): string[][];
4
+
5
+ export function buildCopyRegistry(raw: string): {
6
+ header: string[];
7
+ rows: Array<{
8
+ key: string;
9
+ module: string;
10
+ page: string;
11
+ component: string;
12
+ slot: string;
13
+ text: string;
14
+ row: number;
15
+ }>;
16
+ map: Map<
17
+ string,
18
+ {
19
+ key: string;
20
+ module: string;
21
+ page: string;
22
+ component: string;
23
+ slot: string;
24
+ text: string;
25
+ row: number;
26
+ }
27
+ >;
28
+ duplicates: Map<string, number[]>;
29
+ missingColumns: string[];
30
+ };
31
+
32
+ export function normalizeCopyText(text: unknown): string;
33
+ export function interpolateCopyText(text: string, params?: Record<string, unknown>): string;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ const DEFAULT_INSFORGE_BASE_URL = "https://5tmappuk.us-east.insforge.app";
4
+ const DEFAULT_DASHBOARD_URL = "https://www.vibeusage.cc";
5
+ const DEFAULT_HTTP_TIMEOUT_MS = 20_000;
6
+
7
+ module.exports = {
8
+ DEFAULT_INSFORGE_BASE_URL,
9
+ DEFAULT_DASHBOARD_URL,
10
+ DEFAULT_HTTP_TIMEOUT_MS,
11
+ };
@@ -0,0 +1,3 @@
1
+ export const DEFAULT_INSFORGE_BASE_URL: string;
2
+ export const DEFAULT_DASHBOARD_URL: string;
3
+ export const DEFAULT_HTTP_TIMEOUT_MS: number;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ const FUNCTION_PREFIX = "/functions";
4
+ const LEGACY_FUNCTION_PREFIX = "/api/functions";
5
+ const BACKEND_RUNTIME_UNAVAILABLE_MESSAGE =
6
+ "Backend runtime unavailable (InsForge). Please retry later.";
7
+
8
+ const FUNCTION_SLUGS = Object.freeze({
9
+ deviceTokenIssue: "vibeusage-device-token-issue",
10
+ ingest: "vibeusage-ingest",
11
+ syncPing: "vibeusage-sync-ping",
12
+ usageSummary: "vibeusage-usage-summary",
13
+ usageDaily: "vibeusage-usage-daily",
14
+ usageHourly: "vibeusage-usage-hourly",
15
+ usageMonthly: "vibeusage-usage-monthly",
16
+ usageHeatmap: "vibeusage-usage-heatmap",
17
+ usageModelBreakdown: "vibeusage-usage-model-breakdown",
18
+ projectUsageSummary: "vibeusage-project-usage-summary",
19
+ leaderboard: "vibeusage-leaderboard",
20
+ leaderboardProfile: "vibeusage-leaderboard-profile",
21
+ userStatus: "vibeusage-user-status",
22
+ viewerIdentity: "vibeusage-viewer-identity",
23
+ linkCodeInit: "vibeusage-link-code-init",
24
+ linkCodeExchange: "vibeusage-link-code-exchange",
25
+ publicViewProfile: "vibeusage-public-view-profile",
26
+ publicVisibility: "vibeusage-public-visibility",
27
+ });
28
+
29
+ module.exports = {
30
+ FUNCTION_PREFIX,
31
+ LEGACY_FUNCTION_PREFIX,
32
+ BACKEND_RUNTIME_UNAVAILABLE_MESSAGE,
33
+ FUNCTION_SLUGS,
34
+ };
@@ -0,0 +1,4 @@
1
+ export const FUNCTION_PREFIX: string;
2
+ export const LEGACY_FUNCTION_PREFIX: string;
3
+ export const BACKEND_RUNTIME_UNAVAILABLE_MESSAGE: string;
4
+ export const FUNCTION_SLUGS: Record<string, string>;
@@ -1,41 +0,0 @@
1
- const { checkAndActivate } = require("../lib/activation-check");
2
-
3
- /**
4
- * 检测并激活未配置的 AI CLI 集成
5
- * 用于 hooks 或其他触发器调用
6
- */
7
- async function cmdActivateIfNeeded(argv) {
8
- const opts = parseArgs(argv);
9
-
10
- const results = await checkAndActivate({
11
- silent: opts.silent,
12
- autoConfigure: true,
13
- });
14
-
15
- if (!opts.silent) {
16
- if (results.length === 0) {
17
- console.log("所有 AI CLI 集成已配置完成");
18
- } else {
19
- for (const r of results) {
20
- const icon = r.action === "configured" ? "✅" : "❌";
21
- console.log(`${icon} ${r.displayName}: ${r.action}`);
22
- }
23
- }
24
- }
25
-
26
- // 如果有任何配置成功,返回 0,否则返回 1
27
- const hasSuccess = results.some(r => r.action === "configured");
28
- process.exitCode = hasSuccess ? 0 : 0; // 始终返回 0,不阻塞调用方
29
- }
30
-
31
- function parseArgs(argv) {
32
- const out = {
33
- silent: false,
34
- };
35
- for (const a of argv) {
36
- if (a === "--silent") out.silent = true;
37
- }
38
- return out;
39
- }
40
-
41
- module.exports = { cmdActivateIfNeeded };
@@ -1,341 +0,0 @@
1
- const os = require("node:os");
2
- const path = require("node:path");
3
- const fs = require("node:fs/promises");
4
- const { readJson } = require("./fs");
5
-
6
- /**
7
- * 跨 AI CLI 自动激活检测
8
- * 在 vibeusage 各种命令执行时顺带检测并完成配置
9
- */
10
-
11
- const AI_CLIS = [
12
- {
13
- name: "codex",
14
- displayName: "Codex",
15
- checkInstalled: checkCodexInstalled,
16
- checkConfigured: checkCodexConfigured,
17
- configure: configureCodex,
18
- },
19
- {
20
- name: "claude-code",
21
- displayName: "Claude Code",
22
- checkInstalled: checkClaudeCodeInstalled,
23
- checkConfigured: checkClaudeCodeConfigured,
24
- configure: configureClaudeCode,
25
- },
26
- {
27
- name: "opencode",
28
- displayName: "OpenCode",
29
- checkInstalled: checkOpencodeInstalled,
30
- checkConfigured: checkOpencodeConfigured,
31
- configure: configureOpencode,
32
- },
33
- {
34
- name: "every-code",
35
- displayName: "Every Code",
36
- checkInstalled: checkEveryCodeInstalled,
37
- checkConfigured: checkEveryCodeConfigured,
38
- configure: configureEveryCode,
39
- },
40
- {
41
- name: "openclaw",
42
- displayName: "OpenClaw",
43
- checkInstalled: checkOpenclawInstalled,
44
- checkConfigured: checkOpenclawConfigured,
45
- configure: configureOpenclaw,
46
- },
47
- ];
48
-
49
- /**
50
- * 检测所有 AI CLI 并自动配置未完成的
51
- * @param {Object} options
52
- * @param {string} options.home - home目录
53
- * @param {boolean} options.silent - 是否静默模式
54
- * @param {boolean} options.autoConfigure - 是否自动配置(否则仅提示)
55
- */
56
- async function checkAndActivate({ home = os.homedir(), silent = true, autoConfigure = true } = {}) {
57
- const results = [];
58
-
59
- for (const cli of AI_CLIS) {
60
- try {
61
- const isInstalled = await cli.checkInstalled({ home });
62
- if (!isInstalled) continue;
63
-
64
- const isConfigured = await cli.checkConfigured({ home });
65
- if (isConfigured) continue;
66
-
67
- // 发现已安装但未配置的 CLI
68
- if (autoConfigure) {
69
- const success = await cli.configure({ home, silent });
70
- results.push({
71
- name: cli.name,
72
- displayName: cli.displayName,
73
- action: success ? "configured" : "failed",
74
- });
75
-
76
- if (!silent && success) {
77
- console.log(`✅ 已自动配置 ${cli.displayName} 集成`);
78
- }
79
- } else {
80
- results.push({
81
- name: cli.name,
82
- displayName: cli.displayName,
83
- action: "pending",
84
- });
85
-
86
- if (!silent) {
87
- console.log(`⏳ 检测到 ${cli.displayName} 未配置,运行 'vibeusage init' 以配置`);
88
- }
89
- }
90
- } catch (err) {
91
- // 静默忽略错误,不影响主流程
92
- if (!silent) {
93
- console.error(`检查 ${cli.displayName} 失败:`, err.message);
94
- }
95
- }
96
- }
97
-
98
- return results;
99
- }
100
-
101
- // ===== Codex 检测与配置 =====
102
-
103
- async function checkCodexInstalled({ home }) {
104
- const configPath = path.join(home, ".codex", "config.toml");
105
- try {
106
- await fs.access(configPath);
107
- return true;
108
- } catch {
109
- return false;
110
- }
111
- }
112
-
113
- async function checkCodexConfigured({ home }) {
114
- const configPath = path.join(home, ".codex", "config.toml");
115
- try {
116
- const content = await fs.readFile(configPath, "utf8");
117
- // 检查是否已配置 notify
118
- return content.includes("vibeusage") || content.includes("notify");
119
- } catch {
120
- return false;
121
- }
122
- }
123
-
124
- async function configureCodex({ home, silent }) {
125
- try {
126
- // 使用现有的 codex-config 模块
127
- const { upsertCodexNotify } = require("./codex-config");
128
- const notifyCmd = path.join(home, ".vibeusage", "bin", "notify.cjs");
129
- const codexConfigPath = path.join(home, ".codex", "config.toml");
130
- const notifyOriginalPath = path.join(home, ".vibeusage", "backups", "codex-notify-original.json");
131
-
132
- await upsertCodexNotify({
133
- codexConfigPath,
134
- notifyCmd,
135
- notifyOriginalPath,
136
- });
137
- return true;
138
- } catch (err) {
139
- if (!silent) console.error("配置 Codex 失败:", err.message);
140
- return false;
141
- }
142
- }
143
-
144
- // ===== Claude Code 检测与配置 =====
145
-
146
- async function checkClaudeCodeInstalled({ home }) {
147
- const settingsPath = path.join(home, ".claude", "settings.json");
148
- try {
149
- await fs.access(settingsPath);
150
- return true;
151
- } catch {
152
- return false;
153
- }
154
- }
155
-
156
- async function checkClaudeCodeConfigured({ home }) {
157
- const settingsPath = path.join(home, ".claude", "settings.json");
158
- try {
159
- const settings = await readJson(settingsPath);
160
- // 检查是否已有 vibeusage 相关的 hook
161
- const hooks = settings?.hooks?.SessionStart || [];
162
- return hooks.some(h =>
163
- h.hooks?.some(hook => hook.command?.includes("vibeusage"))
164
- );
165
- } catch {
166
- return false;
167
- }
168
- }
169
-
170
- async function configureClaudeCode({ home, silent }) {
171
- try {
172
- const settingsPath = path.join(home, ".claude", "settings.json");
173
- const settings = (await readJson(settingsPath)) || {};
174
-
175
- // 添加 SessionStart hook
176
- if (!settings.hooks) settings.hooks = {};
177
- if (!settings.hooks.SessionStart) settings.hooks.SessionStart = [];
178
-
179
- // 检查是否已存在
180
- const exists = settings.hooks.SessionStart.some(h =>
181
- h.matcher === "startup" &&
182
- h.hooks?.some(hook => hook.command?.includes("vibeusage activate-if-needed"))
183
- );
184
-
185
- if (!exists) {
186
- settings.hooks.SessionStart.push({
187
- matcher: "startup",
188
- hooks: [{
189
- type: "command",
190
- command: "vibeusage activate-if-needed --silent 2>/dev/null || true"
191
- }]
192
- });
193
-
194
- await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
195
- }
196
- return true;
197
- } catch (err) {
198
- if (!silent) console.error("配置 Claude Code 失败:", err.message);
199
- return false;
200
- }
201
- }
202
-
203
- // ===== OpenCode 检测与配置 =====
204
-
205
- async function checkOpencodeInstalled({ home }) {
206
- const configPath = path.join(home, ".config", "opencode", "opencode.json");
207
- try {
208
- await fs.access(configPath);
209
- return true;
210
- } catch {
211
- return false;
212
- }
213
- }
214
-
215
- async function checkOpencodeConfigured({ home }) {
216
- const pluginDir = path.join(home, ".config", "opencode", "plugins");
217
- try {
218
- const files = await fs.readdir(pluginDir);
219
- return files.some(f => f.includes("vibeusage"));
220
- } catch {
221
- return false;
222
- }
223
- }
224
-
225
- async function configureOpencode({ home, silent }) {
226
- try {
227
- const pluginDir = path.join(home, ".config", "opencode", "plugins");
228
- await fs.mkdir(pluginDir, { recursive: true });
229
-
230
- const pluginPath = path.join(pluginDir, "vibeusage-activation.js");
231
- const pluginCode = `export const VibeusageActivation = async ({ $ }) => {
232
- return {
233
- "session.created": async () => {
234
- await $'vibeusage activate-if-needed --silent'.quiet().nothrow();
235
- }
236
- };
237
- };`;
238
-
239
- await fs.writeFile(pluginPath, pluginCode, "utf8");
240
- return true;
241
- } catch (err) {
242
- if (!silent) console.error("配置 OpenCode 失败:", err.message);
243
- return false;
244
- }
245
- }
246
-
247
- // ===== Every Code 检测与配置 =====
248
-
249
- async function checkEveryCodeInstalled({ home }) {
250
- const configPath = path.join(home, ".code", "config.toml");
251
- try {
252
- await fs.access(configPath);
253
- return true;
254
- } catch {
255
- return false;
256
- }
257
- }
258
-
259
- async function checkEveryCodeConfigured({ home }) {
260
- const configPath = path.join(home, ".code", "config.toml");
261
- try {
262
- const content = await fs.readFile(configPath, "utf8");
263
- return content.includes("vibeusage");
264
- } catch {
265
- return false;
266
- }
267
- }
268
-
269
- async function configureEveryCode({ home, silent }) {
270
- try {
271
- // Every Code 配置类似 Codex
272
- const configPath = path.join(home, ".code", "config.toml");
273
- let content = "";
274
- try {
275
- content = await fs.readFile(configPath, "utf8");
276
- } catch {
277
- content = "";
278
- }
279
-
280
- const notifyCmd = path.join(home, ".vibeusage", "bin", "notify.cjs");
281
- const notifyLine = `notify = ["/usr/bin/env", "node", "${notifyCmd}"]`;
282
-
283
- if (!content.includes("vibeusage")) {
284
- content = content.trim() + "\n\n# vibeusage integration\n" + notifyLine + "\n";
285
- await fs.writeFile(configPath, content, "utf8");
286
- }
287
- return true;
288
- } catch (err) {
289
- if (!silent) console.error("配置 Every Code 失败:", err.message);
290
- return false;
291
- }
292
- }
293
-
294
- module.exports = {
295
- checkAndActivate,
296
- AI_CLIS,
297
- };
298
-
299
- // ===== OpenClaw 检测与配置 =====
300
-
301
- async function checkOpenclawInstalled({ home }) {
302
- const configPath = path.join(home, ".openclaw", "openclaw.json");
303
- try {
304
- await fs.access(configPath);
305
- return true;
306
- } catch {
307
- return false;
308
- }
309
- }
310
-
311
- async function checkOpenclawConfigured({ home }) {
312
- const { probeOpenclawSessionPluginState } = require("./openclaw-session-plugin");
313
- const { resolveTrackerPaths } = require("./tracker-paths");
314
- try {
315
- const { trackerDir } = await resolveTrackerPaths({ home });
316
- const state = await probeOpenclawSessionPluginState({ home, trackerDir, env: process.env });
317
- return state?.configured === true;
318
- } catch {
319
- return false;
320
- }
321
- }
322
-
323
- async function configureOpenclaw({ home, silent }) {
324
- try {
325
- const { installOpenclawSessionPlugin } = require("./openclaw-session-plugin");
326
- const { resolveTrackerPaths } = require("./tracker-paths");
327
- const { trackerDir } = await resolveTrackerPaths({ home });
328
-
329
- const result = await installOpenclawSessionPlugin({
330
- home,
331
- trackerDir,
332
- packageName: "vibeusage",
333
- env: process.env,
334
- });
335
-
336
- return result?.configured === true;
337
- } catch (err) {
338
- if (!silent) console.error("配置 OpenClaw 失败:", err.message);
339
- return false;
340
- }
341
- }