vibeusage 0.2.21 → 0.2.22
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/README.md +306 -173
- package/README.old.md +324 -0
- package/README.zh-CN.md +304 -188
- package/package.json +32 -32
- package/src/cli.js +41 -37
- package/src/commands/activate-if-needed.js +41 -0
- package/src/commands/diagnostics.js +8 -9
- package/src/commands/doctor.js +31 -26
- package/src/commands/init.js +285 -218
- package/src/commands/status.js +86 -83
- package/src/commands/sync.js +182 -130
- package/src/commands/uninstall.js +66 -62
- package/src/lib/activation-check.js +290 -0
- package/src/lib/browser-auth.js +52 -54
- package/src/lib/claude-config.js +25 -25
- package/src/lib/cli-ui.js +35 -35
- package/src/lib/codex-config.js +40 -36
- package/src/lib/debug-flags.js +2 -2
- package/src/lib/diagnostics.js +70 -57
- package/src/lib/doctor.js +139 -132
- package/src/lib/fs.js +17 -17
- package/src/lib/gemini-config.js +44 -40
- package/src/lib/init-flow.js +16 -22
- package/src/lib/insforge-client.js +10 -10
- package/src/lib/insforge.js +9 -3
- package/src/lib/openclaw-hook.js +89 -66
- package/src/lib/openclaw-session-plugin.js +116 -92
- package/src/lib/opencode-config.js +31 -32
- package/src/lib/opencode-usage-audit.js +34 -31
- package/src/lib/progress.js +12 -13
- package/src/lib/project-usage-purge.js +23 -17
- package/src/lib/prompt.js +8 -4
- package/src/lib/rollout.js +342 -241
- package/src/lib/runtime-config.js +34 -22
- package/src/lib/subscriptions.js +94 -92
- package/src/lib/tracker-paths.js +6 -6
- package/src/lib/upload-throttle.js +35 -16
- package/src/lib/uploader.js +33 -29
- package/src/lib/vibeusage-api.js +72 -56
- package/src/lib/vibeusage-public-repo.js +41 -24
package/src/commands/status.js
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
const os = require(
|
|
2
|
-
const path = require(
|
|
3
|
-
const fs = require(
|
|
1
|
+
const os = require("node:os");
|
|
2
|
+
const path = require("node:path");
|
|
3
|
+
const fs = require("node:fs/promises");
|
|
4
4
|
|
|
5
|
-
const { readJson } = require(
|
|
6
|
-
const { readCodexNotify, readEveryCodeNotify } = require(
|
|
7
|
-
const { isClaudeHookConfigured, buildClaudeHookCommand } = require(
|
|
5
|
+
const { readJson } = require("../lib/fs");
|
|
6
|
+
const { readCodexNotify, readEveryCodeNotify } = require("../lib/codex-config");
|
|
7
|
+
const { isClaudeHookConfigured, buildClaudeHookCommand } = require("../lib/claude-config");
|
|
8
8
|
const {
|
|
9
9
|
resolveGeminiConfigDir,
|
|
10
10
|
resolveGeminiSettingsPath,
|
|
11
11
|
isGeminiHookConfigured,
|
|
12
|
-
buildGeminiHookCommand
|
|
13
|
-
} = require(
|
|
14
|
-
const { resolveOpencodeConfigDir, isOpencodePluginInstalled } = require(
|
|
15
|
-
const { collectLocalSubscriptions } = require(
|
|
16
|
-
const { normalizeState: normalizeUploadState } = require(
|
|
17
|
-
const { collectTrackerDiagnostics } = require(
|
|
18
|
-
const { probeOpenclawHookState } = require(
|
|
19
|
-
const { probeOpenclawSessionPluginState } = require(
|
|
20
|
-
const { resolveTrackerPaths } = require(
|
|
12
|
+
buildGeminiHookCommand,
|
|
13
|
+
} = require("../lib/gemini-config");
|
|
14
|
+
const { resolveOpencodeConfigDir, isOpencodePluginInstalled } = require("../lib/opencode-config");
|
|
15
|
+
const { collectLocalSubscriptions } = require("../lib/subscriptions");
|
|
16
|
+
const { normalizeState: normalizeUploadState } = require("../lib/upload-throttle");
|
|
17
|
+
const { collectTrackerDiagnostics } = require("../lib/diagnostics");
|
|
18
|
+
const { probeOpenclawHookState } = require("../lib/openclaw-hook");
|
|
19
|
+
const { probeOpenclawSessionPluginState } = require("../lib/openclaw-session-plugin");
|
|
20
|
+
const { resolveTrackerPaths } = require("../lib/tracker-paths");
|
|
21
21
|
|
|
22
22
|
async function cmdStatus(argv = []) {
|
|
23
23
|
const opts = parseArgs(argv);
|
|
24
24
|
if (opts.diagnostics) {
|
|
25
25
|
const diagnostics = await collectTrackerDiagnostics();
|
|
26
|
-
process.stdout.write(JSON.stringify(diagnostics, null, 2) +
|
|
26
|
+
process.stdout.write(JSON.stringify(diagnostics, null, 2) + "\n");
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
const home = os.homedir();
|
|
31
31
|
const { trackerDir, binDir } = await resolveTrackerPaths({ home });
|
|
32
|
-
const configPath = path.join(trackerDir,
|
|
33
|
-
const queuePath = path.join(trackerDir,
|
|
34
|
-
const queueStatePath = path.join(trackerDir,
|
|
35
|
-
const cursorsPath = path.join(trackerDir,
|
|
36
|
-
const notifySignalPath = path.join(trackerDir,
|
|
37
|
-
const openclawSignalPath = path.join(trackerDir,
|
|
38
|
-
const throttlePath = path.join(trackerDir,
|
|
39
|
-
const uploadThrottlePath = path.join(trackerDir,
|
|
40
|
-
const autoRetryPath = path.join(trackerDir,
|
|
41
|
-
const codexHome = process.env.CODEX_HOME || path.join(home,
|
|
42
|
-
const codexConfigPath = path.join(codexHome,
|
|
43
|
-
const codeHome = process.env.CODE_HOME || path.join(home,
|
|
44
|
-
const codeConfigPath = path.join(codeHome,
|
|
45
|
-
const claudeSettingsPath = path.join(home,
|
|
32
|
+
const configPath = path.join(trackerDir, "config.json");
|
|
33
|
+
const queuePath = path.join(trackerDir, "queue.jsonl");
|
|
34
|
+
const queueStatePath = path.join(trackerDir, "queue.state.json");
|
|
35
|
+
const cursorsPath = path.join(trackerDir, "cursors.json");
|
|
36
|
+
const notifySignalPath = path.join(trackerDir, "notify.signal");
|
|
37
|
+
const openclawSignalPath = path.join(trackerDir, "openclaw.signal");
|
|
38
|
+
const throttlePath = path.join(trackerDir, "sync.throttle");
|
|
39
|
+
const uploadThrottlePath = path.join(trackerDir, "upload.throttle.json");
|
|
40
|
+
const autoRetryPath = path.join(trackerDir, "auto.retry.json");
|
|
41
|
+
const codexHome = process.env.CODEX_HOME || path.join(home, ".codex");
|
|
42
|
+
const codexConfigPath = path.join(codexHome, "config.toml");
|
|
43
|
+
const codeHome = process.env.CODE_HOME || path.join(home, ".code");
|
|
44
|
+
const codeConfigPath = path.join(codeHome, "config.toml");
|
|
45
|
+
const claudeSettingsPath = path.join(home, ".claude", "settings.json");
|
|
46
46
|
const geminiConfigDir = resolveGeminiConfigDir({ home, env: process.env });
|
|
47
47
|
const geminiSettingsPath = resolveGeminiSettingsPath({ configDir: geminiConfigDir });
|
|
48
48
|
const opencodeConfigDir = resolveOpencodeConfigDir({ home, env: process.env });
|
|
49
|
-
const notifyPath = path.join(binDir,
|
|
49
|
+
const notifyPath = path.join(binDir, "notify.cjs");
|
|
50
50
|
const claudeHookCommand = buildClaudeHookCommand(notifyPath);
|
|
51
51
|
const geminiHookCommand = buildGeminiHookCommand(notifyPath);
|
|
52
52
|
|
|
@@ -69,30 +69,36 @@ async function cmdStatus(argv = []) {
|
|
|
69
69
|
const everyCodeConfigured = Array.isArray(everyCodeNotify) && everyCodeNotify.length > 0;
|
|
70
70
|
const claudeHookConfigured = await isClaudeHookConfigured({
|
|
71
71
|
settingsPath: claudeSettingsPath,
|
|
72
|
-
hookCommand: claudeHookCommand
|
|
72
|
+
hookCommand: claudeHookCommand,
|
|
73
73
|
});
|
|
74
74
|
const geminiHookConfigured = await isGeminiHookConfigured({
|
|
75
75
|
settingsPath: geminiSettingsPath,
|
|
76
|
-
hookCommand: geminiHookCommand
|
|
76
|
+
hookCommand: geminiHookCommand,
|
|
77
|
+
});
|
|
78
|
+
const opencodePluginConfigured = await isOpencodePluginInstalled({
|
|
79
|
+
configDir: opencodeConfigDir,
|
|
80
|
+
});
|
|
81
|
+
const openclawSessionPluginState = await probeOpenclawSessionPluginState({
|
|
82
|
+
home,
|
|
83
|
+
trackerDir,
|
|
84
|
+
env: process.env,
|
|
77
85
|
});
|
|
78
|
-
const opencodePluginConfigured = await isOpencodePluginInstalled({ configDir: opencodeConfigDir });
|
|
79
|
-
const openclawSessionPluginState = await probeOpenclawSessionPluginState({ home, trackerDir, env: process.env });
|
|
80
86
|
const openclawHookState = await probeOpenclawHookState({ home, trackerDir, env: process.env });
|
|
81
87
|
|
|
82
88
|
const lastUpload = uploadThrottle.lastSuccessMs
|
|
83
89
|
? parseEpochMsToIso(uploadThrottle.lastSuccessMs)
|
|
84
|
-
: typeof queueState.updatedAt ===
|
|
90
|
+
: typeof queueState.updatedAt === "string"
|
|
85
91
|
? queueState.updatedAt
|
|
86
92
|
: null;
|
|
87
93
|
const nextUpload = parseEpochMsToIso(uploadThrottle.nextAllowedAtMs || null);
|
|
88
94
|
const backoffUntil = parseEpochMsToIso(uploadThrottle.backoffUntilMs || null);
|
|
89
95
|
const lastUploadError = uploadThrottle.lastError
|
|
90
|
-
? `${uploadThrottle.lastErrorAt ||
|
|
96
|
+
? `${uploadThrottle.lastErrorAt || "unknown"} ${uploadThrottle.lastError}`
|
|
91
97
|
: null;
|
|
92
98
|
const autoRetryAt = parseEpochMsToIso(autoRetry?.retryAtMs || null);
|
|
93
99
|
const autoRetryLine = autoRetryAt
|
|
94
|
-
? `- Auto retry after: ${autoRetryAt} (${autoRetry?.reason ||
|
|
95
|
-
autoRetry?.pendingBytes || 0
|
|
100
|
+
? `- Auto retry after: ${autoRetryAt} (${autoRetry?.reason || "scheduled"}, pending ${Number(
|
|
101
|
+
autoRetry?.pendingBytes || 0,
|
|
96
102
|
)} bytes)`
|
|
97
103
|
: null;
|
|
98
104
|
|
|
@@ -100,70 +106,68 @@ async function cmdStatus(argv = []) {
|
|
|
100
106
|
home,
|
|
101
107
|
env: process.env,
|
|
102
108
|
probeKeychain: opts.probeKeychain,
|
|
103
|
-
probeKeychainDetails: opts.probeKeychainDetails
|
|
109
|
+
probeKeychainDetails: opts.probeKeychainDetails,
|
|
104
110
|
});
|
|
105
111
|
const subscriptionLines =
|
|
106
|
-
subscriptions.length > 0
|
|
107
|
-
? subscriptions.map(formatSubscriptionLine)
|
|
108
|
-
: [];
|
|
112
|
+
subscriptions.length > 0 ? subscriptions.map(formatSubscriptionLine) : [];
|
|
109
113
|
|
|
110
114
|
process.stdout.write(
|
|
111
115
|
[
|
|
112
|
-
|
|
113
|
-
`- Base URL: ${config?.baseUrl ||
|
|
114
|
-
`- Device token: ${config?.deviceToken ?
|
|
116
|
+
"Status:",
|
|
117
|
+
`- Base URL: ${config?.baseUrl || "unset"}`,
|
|
118
|
+
`- Device token: ${config?.deviceToken ? "set" : "unset"}`,
|
|
115
119
|
`- Queue: ${pendingBytes} bytes pending`,
|
|
116
|
-
`- Last parse: ${cursors?.updatedAt ||
|
|
117
|
-
`- Last notify: ${lastNotify ||
|
|
118
|
-
`- Last OpenClaw-triggered sync: ${lastOpenclawSync ||
|
|
119
|
-
`- Last notify-triggered sync: ${lastNotifySpawn ||
|
|
120
|
-
`- Last upload: ${lastUpload ||
|
|
121
|
-
`- Next upload after: ${nextUpload ||
|
|
122
|
-
`- Backoff until: ${backoffUntil ||
|
|
120
|
+
`- Last parse: ${cursors?.updatedAt || "never"}`,
|
|
121
|
+
`- Last notify: ${lastNotify || "never"}`,
|
|
122
|
+
`- Last OpenClaw-triggered sync: ${lastOpenclawSync || "never"}`,
|
|
123
|
+
`- Last notify-triggered sync: ${lastNotifySpawn || "never"}`,
|
|
124
|
+
`- Last upload: ${lastUpload || "never"}`,
|
|
125
|
+
`- Next upload after: ${nextUpload || "never"}`,
|
|
126
|
+
`- Backoff until: ${backoffUntil || "never"}`,
|
|
123
127
|
lastUploadError ? `- Last upload error: ${lastUploadError}` : null,
|
|
124
128
|
autoRetryLine,
|
|
125
|
-
`- Codex notify: ${notifyConfigured ? JSON.stringify(codexNotify) :
|
|
126
|
-
`- Every Code notify: ${everyCodeConfigured ? JSON.stringify(everyCodeNotify) :
|
|
127
|
-
`- Claude hooks: ${claudeHookConfigured ?
|
|
128
|
-
`- Gemini hooks: ${geminiHookConfigured ?
|
|
129
|
-
`- Opencode plugin: ${opencodePluginConfigured ?
|
|
130
|
-
`- OpenClaw session plugin: ${openclawSessionPluginState?.configured ?
|
|
131
|
-
`- OpenClaw hook (legacy): ${openclawHookState?.configured ?
|
|
129
|
+
`- Codex notify: ${notifyConfigured ? JSON.stringify(codexNotify) : "unset"}`,
|
|
130
|
+
`- Every Code notify: ${everyCodeConfigured ? JSON.stringify(everyCodeNotify) : "unset"}`,
|
|
131
|
+
`- Claude hooks: ${claudeHookConfigured ? "set" : "unset"}`,
|
|
132
|
+
`- Gemini hooks: ${geminiHookConfigured ? "set" : "unset"}`,
|
|
133
|
+
`- Opencode plugin: ${opencodePluginConfigured ? "set" : "unset"}`,
|
|
134
|
+
`- OpenClaw session plugin: ${openclawSessionPluginState?.configured ? "set" : "unset"}`,
|
|
135
|
+
`- OpenClaw hook (legacy): ${openclawHookState?.configured ? "set" : "unset"}`,
|
|
132
136
|
...subscriptionLines,
|
|
133
|
-
|
|
137
|
+
"",
|
|
134
138
|
]
|
|
135
139
|
.filter(Boolean)
|
|
136
|
-
.join(
|
|
140
|
+
.join("\n"),
|
|
137
141
|
);
|
|
138
142
|
}
|
|
139
143
|
|
|
140
144
|
function formatSubscriptionLine(entry = {}) {
|
|
141
|
-
const tool = String(entry.tool ||
|
|
142
|
-
const provider = String(entry.provider ||
|
|
143
|
-
const product = String(entry.product ||
|
|
144
|
-
const planType = String(entry.planType ||
|
|
145
|
-
const rateLimitTier = String(entry.rateLimitTier ||
|
|
145
|
+
const tool = String(entry.tool || "");
|
|
146
|
+
const provider = String(entry.provider || "");
|
|
147
|
+
const product = String(entry.product || "");
|
|
148
|
+
const planType = String(entry.planType || "");
|
|
149
|
+
const rateLimitTier = String(entry.rateLimitTier || "");
|
|
146
150
|
const toolLabel =
|
|
147
|
-
tool ===
|
|
148
|
-
?
|
|
149
|
-
: tool ===
|
|
150
|
-
?
|
|
151
|
-
: tool ===
|
|
152
|
-
?
|
|
151
|
+
tool === "codex"
|
|
152
|
+
? "Codex"
|
|
153
|
+
: tool === "opencode"
|
|
154
|
+
? "OpenCode"
|
|
155
|
+
: tool === "claude"
|
|
156
|
+
? "Claude Code"
|
|
153
157
|
: tool;
|
|
154
158
|
|
|
155
159
|
if (!planType) return null;
|
|
156
160
|
|
|
157
|
-
if (tool ===
|
|
158
|
-
const suffix = rateLimitTier ? ` (rate limit tier: ${rateLimitTier})` :
|
|
161
|
+
if (tool === "claude" && provider === "anthropic" && product === "subscription") {
|
|
162
|
+
const suffix = rateLimitTier ? ` (rate limit tier: ${rateLimitTier})` : "";
|
|
159
163
|
return `- ${toolLabel} subscription: ${planType}${suffix}`;
|
|
160
164
|
}
|
|
161
165
|
|
|
162
|
-
if (provider ===
|
|
166
|
+
if (provider === "openai" && product === "chatgpt") {
|
|
163
167
|
return `- ${toolLabel} ChatGPT plan: ${planType}`;
|
|
164
168
|
}
|
|
165
169
|
|
|
166
|
-
const productLabel = product ? product.replace(/_/g,
|
|
170
|
+
const productLabel = product ? product.replace(/_/g, " ") : "subscription";
|
|
167
171
|
return `- ${toolLabel} ${productLabel}: ${planType}`;
|
|
168
172
|
}
|
|
169
173
|
|
|
@@ -172,13 +176,12 @@ function parseArgs(argv) {
|
|
|
172
176
|
|
|
173
177
|
for (let i = 0; i < argv.length; i++) {
|
|
174
178
|
const a = argv[i];
|
|
175
|
-
if (a ===
|
|
176
|
-
else if (a ===
|
|
177
|
-
else if (a ===
|
|
179
|
+
if (a === "--diagnostics" || a === "--json") out.diagnostics = true;
|
|
180
|
+
else if (a === "--probe-keychain") out.probeKeychain = true;
|
|
181
|
+
else if (a === "--probe-keychain-details") {
|
|
178
182
|
out.probeKeychainDetails = true;
|
|
179
183
|
out.probeKeychain = true;
|
|
180
|
-
}
|
|
181
|
-
else throw new Error(`Unknown option: ${a}`);
|
|
184
|
+
} else throw new Error(`Unknown option: ${a}`);
|
|
182
185
|
}
|
|
183
186
|
|
|
184
187
|
return out;
|
|
@@ -195,7 +198,7 @@ async function safeStatSize(p) {
|
|
|
195
198
|
|
|
196
199
|
async function safeReadText(p) {
|
|
197
200
|
try {
|
|
198
|
-
return await fs.readFile(p,
|
|
201
|
+
return await fs.readFile(p, "utf8");
|
|
199
202
|
} catch (_e) {
|
|
200
203
|
return null;
|
|
201
204
|
}
|