vibeusage 0.3.0 → 0.3.2
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 +19 -11
- package/README.zh-CN.md +10 -8
- package/node_modules/@insforge/sdk/LICENSE +201 -201
- package/node_modules/@insforge/sdk/README.md +326 -259
- package/node_modules/@insforge/sdk/dist/index.d.mts +377 -182
- package/node_modules/@insforge/sdk/dist/index.d.ts +377 -182
- package/node_modules/@insforge/sdk/dist/index.js +1172 -677
- package/node_modules/@insforge/sdk/dist/index.js.map +1 -1
- package/node_modules/@insforge/sdk/dist/index.mjs +1171 -677
- package/node_modules/@insforge/sdk/dist/index.mjs.map +1 -1
- package/node_modules/@insforge/sdk/package.json +68 -68
- package/node_modules/@insforge/shared-schemas/dist/ai-api.schema.d.ts +1120 -43
- package/node_modules/@insforge/shared-schemas/dist/ai-api.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/ai-api.schema.js +179 -5
- package/node_modules/@insforge/shared-schemas/dist/ai-api.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/ai.schema.d.ts +25 -25
- package/node_modules/@insforge/shared-schemas/dist/ai.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/ai.schema.js +2 -2
- package/node_modules/@insforge/shared-schemas/dist/ai.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/auth-api.schema.d.ts +197 -51
- package/node_modules/@insforge/shared-schemas/dist/auth-api.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/auth-api.schema.js +87 -23
- package/node_modules/@insforge/shared-schemas/dist/auth-api.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/auth.schema.d.ts +32 -3
- package/node_modules/@insforge/shared-schemas/dist/auth.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/auth.schema.js +21 -3
- package/node_modules/@insforge/shared-schemas/dist/auth.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/cloud-events.schema.d.ts +380 -0
- package/node_modules/@insforge/shared-schemas/dist/cloud-events.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/cloud-events.schema.js +74 -0
- package/node_modules/@insforge/shared-schemas/dist/cloud-events.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/database-api.schema.d.ts +13 -13
- package/node_modules/@insforge/shared-schemas/dist/database-api.schema.js +1 -1
- package/node_modules/@insforge/shared-schemas/dist/database-api.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/deployments-api.schema.d.ts +735 -0
- package/node_modules/@insforge/shared-schemas/dist/deployments-api.schema.d.ts.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/deployments-api.schema.js +209 -0
- package/node_modules/@insforge/shared-schemas/dist/deployments-api.schema.js.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/deployments.schema.d.ts +37 -0
- package/node_modules/@insforge/shared-schemas/dist/deployments.schema.d.ts.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/deployments.schema.js +25 -0
- package/node_modules/@insforge/shared-schemas/dist/deployments.schema.js.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/docs.schema.d.ts +5 -1
- package/node_modules/@insforge/shared-schemas/dist/docs.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/docs.schema.js +34 -4
- package/node_modules/@insforge/shared-schemas/dist/docs.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/email-api.schema.js +1 -1
- package/node_modules/@insforge/shared-schemas/dist/email-api.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/functions-api.schema.d.ts +186 -6
- package/node_modules/@insforge/shared-schemas/dist/functions-api.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/functions-api.schema.js +21 -2
- package/node_modules/@insforge/shared-schemas/dist/functions-api.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/functions.schema.d.ts +5 -5
- package/node_modules/@insforge/shared-schemas/dist/functions.schema.js +1 -1
- package/node_modules/@insforge/shared-schemas/dist/functions.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/index.d.ts +24 -18
- package/node_modules/@insforge/shared-schemas/dist/index.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/index.js +24 -18
- package/node_modules/@insforge/shared-schemas/dist/index.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/logs-api.schema.js +1 -1
- package/node_modules/@insforge/shared-schemas/dist/logs-api.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/logs.schema.d.ts +43 -0
- package/node_modules/@insforge/shared-schemas/dist/logs.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/logs.schema.js +11 -0
- package/node_modules/@insforge/shared-schemas/dist/logs.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/metadata.schema.d.ts +229 -172
- package/node_modules/@insforge/shared-schemas/dist/metadata.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/metadata.schema.js +27 -7
- package/node_modules/@insforge/shared-schemas/dist/metadata.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/rate-limit-api.schema.d.ts +51 -0
- package/node_modules/@insforge/shared-schemas/dist/rate-limit-api.schema.d.ts.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/rate-limit-api.schema.js +31 -0
- package/node_modules/@insforge/shared-schemas/dist/rate-limit-api.schema.js.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/rate-limit.schema.d.ts +31 -0
- package/node_modules/@insforge/shared-schemas/dist/rate-limit.schema.d.ts.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/rate-limit.schema.js +12 -0
- package/node_modules/@insforge/shared-schemas/dist/rate-limit.schema.js.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/realtime-api.schema.d.ts +39 -20
- package/node_modules/@insforge/shared-schemas/dist/realtime-api.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/realtime-api.schema.js +5 -1
- package/node_modules/@insforge/shared-schemas/dist/realtime-api.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/realtime.schema.d.ts +12 -4
- package/node_modules/@insforge/shared-schemas/dist/realtime.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/realtime.schema.js +6 -0
- package/node_modules/@insforge/shared-schemas/dist/realtime.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/schedules-api.schema.d.ts +287 -0
- package/node_modules/@insforge/shared-schemas/dist/schedules-api.schema.d.ts.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/schedules-api.schema.js +81 -0
- package/node_modules/@insforge/shared-schemas/dist/schedules-api.schema.js.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/schedules.schema.d.ts +77 -0
- package/node_modules/@insforge/shared-schemas/dist/schedules.schema.d.ts.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/schedules.schema.js +36 -0
- package/node_modules/@insforge/shared-schemas/dist/schedules.schema.js.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/secrets-api.schema.d.ts +113 -0
- package/node_modules/@insforge/shared-schemas/dist/secrets-api.schema.d.ts.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/secrets-api.schema.js +31 -0
- package/node_modules/@insforge/shared-schemas/dist/secrets-api.schema.js.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/secrets.schema.d.ts +31 -0
- package/node_modules/@insforge/shared-schemas/dist/secrets.schema.d.ts.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/secrets.schema.js +13 -0
- package/node_modules/@insforge/shared-schemas/dist/secrets.schema.js.map +1 -0
- package/node_modules/@insforge/shared-schemas/dist/storage-api.schema.d.ts +27 -2
- package/node_modules/@insforge/shared-schemas/dist/storage-api.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/storage-api.schema.js +9 -1
- package/node_modules/@insforge/shared-schemas/dist/storage-api.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/storage.schema.d.ts +17 -0
- package/node_modules/@insforge/shared-schemas/dist/storage.schema.d.ts.map +1 -1
- package/node_modules/@insforge/shared-schemas/dist/storage.schema.js +6 -0
- package/node_modules/@insforge/shared-schemas/dist/storage.schema.js.map +1 -1
- package/node_modules/@insforge/shared-schemas/package.json +2 -1
- package/package.json +2 -2
- package/src/commands/status.js +22 -5
- package/src/commands/sync.js +100 -197
- package/src/commands/uninstall.js +0 -11
- package/src/lib/diagnostics.js +34 -9
- package/src/lib/doctor.js +24 -15
- package/src/lib/insforge-client.js +13 -9
- package/src/lib/integrations/context.js +0 -6
- package/src/lib/integrations/index.js +0 -2
- package/src/lib/openclaw-session-plugin.js +48 -138
- package/src/lib/openclaw-usage-ledger.js +237 -0
- package/src/lib/opencode-sqlite.js +113 -0
- package/src/lib/opencode-usage-audit.js +3 -2
- package/src/lib/rollout.js +229 -153
- package/src/lib/vibeusage-api.js +2 -2
- package/src/lib/integrations/openclaw-legacy.js +0 -123
- package/src/lib/openclaw-hook.js +0 -420
|
@@ -93,17 +93,6 @@ async function cmdUninstall(argv) {
|
|
|
93
93
|
unreadableText: (result) =>
|
|
94
94
|
`- OpenClaw session plugin: skipped (${result.detail || "openclaw config unreadable"})`,
|
|
95
95
|
}),
|
|
96
|
-
renderHookLine({
|
|
97
|
-
exists: true,
|
|
98
|
-
result: resultByName.get("openclaw-legacy"),
|
|
99
|
-
missingText: "- OpenClaw hook (legacy): skipped (openclaw config not found)",
|
|
100
|
-
removedText: (result) =>
|
|
101
|
-
`- OpenClaw hook (legacy) removed: ${result.detail || result.openclawConfigPath || "unknown"}`,
|
|
102
|
-
noChangeText: "- OpenClaw hook (legacy): no change",
|
|
103
|
-
skippedText: "- OpenClaw hook (legacy): no change",
|
|
104
|
-
unreadableText: (result) =>
|
|
105
|
-
`- OpenClaw hook (legacy): skipped (${result.detail || "openclaw config unreadable"})`,
|
|
106
|
-
}),
|
|
107
96
|
opts.purge ? `- Purged: ${path.join(home, ".vibeusage")}` : "- Purge: skipped (use --purge)",
|
|
108
97
|
"",
|
|
109
98
|
].join("\n"),
|
package/src/lib/diagnostics.js
CHANGED
|
@@ -11,6 +11,10 @@ async function collectTrackerDiagnostics({
|
|
|
11
11
|
codexHome = process.env.CODEX_HOME || path.join(home, ".codex"),
|
|
12
12
|
codeHome = process.env.CODE_HOME || path.join(home, ".code"),
|
|
13
13
|
} = {}) {
|
|
14
|
+
const xdgDataHome = process.env.XDG_DATA_HOME || path.join(home, ".local", "share");
|
|
15
|
+
const opencodeHome = process.env.OPENCODE_HOME || path.join(xdgDataHome, "opencode");
|
|
16
|
+
const opencodeStorageDir = path.join(opencodeHome, "storage");
|
|
17
|
+
const opencodeDbPath = path.join(opencodeHome, "opencode.db");
|
|
14
18
|
const integrationContext = await createIntegrationContext({
|
|
15
19
|
home,
|
|
16
20
|
env: {
|
|
@@ -39,6 +43,9 @@ async function collectTrackerDiagnostics({
|
|
|
39
43
|
const autoRetry = await readJson(autoRetryPath);
|
|
40
44
|
const probes = await probeIntegrations(integrationContext);
|
|
41
45
|
const probeByName = new Map(probes.map((probe) => [probe.name, probe]));
|
|
46
|
+
const opencodeSqliteCursor =
|
|
47
|
+
cursors?.opencodeSqlite && typeof cursors.opencodeSqlite === "object" ? cursors.opencodeSqlite : {};
|
|
48
|
+
const opencodeDbStat = await safeStat(opencodeDbPath);
|
|
42
49
|
|
|
43
50
|
const queueSize = await safeStatSize(queuePath);
|
|
44
51
|
const offsetBytes = Number(queueState.offset || 0);
|
|
@@ -54,7 +61,6 @@ async function collectTrackerDiagnostics({
|
|
|
54
61
|
const geminiProbe = probeByName.get("gemini");
|
|
55
62
|
const opencodeProbe = probeByName.get("opencode");
|
|
56
63
|
const openclawSessionProbe = probeByName.get("openclaw-session");
|
|
57
|
-
const openclawLegacyProbe = probeByName.get("openclaw-legacy");
|
|
58
64
|
|
|
59
65
|
const codexNotify = Array.isArray(codexProbe?.currentNotify)
|
|
60
66
|
? codexProbe.currentNotify.map((value) => redactValue(value, home))
|
|
@@ -106,6 +112,25 @@ async function collectTrackerDiagnostics({
|
|
|
106
112
|
pending_bytes: pendingBytes,
|
|
107
113
|
updated_at: typeof queueState.updatedAt === "string" ? queueState.updatedAt : null,
|
|
108
114
|
},
|
|
115
|
+
opencode: {
|
|
116
|
+
storage_dir: redactValue(opencodeStorageDir, home),
|
|
117
|
+
db_path: redactValue(opencodeDbPath, home),
|
|
118
|
+
sqlite_db_present: Boolean(opencodeDbStat?.isFile?.()),
|
|
119
|
+
sqlite_status:
|
|
120
|
+
typeof opencodeSqliteCursor.lastStatus === "string" && opencodeSqliteCursor.lastStatus.trim()
|
|
121
|
+
? opencodeSqliteCursor.lastStatus.trim()
|
|
122
|
+
: "never_checked",
|
|
123
|
+
sqlite_last_checked_at:
|
|
124
|
+
typeof opencodeSqliteCursor.lastCheckedAt === "string"
|
|
125
|
+
? opencodeSqliteCursor.lastCheckedAt
|
|
126
|
+
: null,
|
|
127
|
+
sqlite_cursor_updated_at:
|
|
128
|
+
typeof opencodeSqliteCursor.updatedAt === "string" ? opencodeSqliteCursor.updatedAt : null,
|
|
129
|
+
sqlite_error_code:
|
|
130
|
+
typeof opencodeSqliteCursor.lastErrorCode === "string"
|
|
131
|
+
? opencodeSqliteCursor.lastErrorCode
|
|
132
|
+
: null,
|
|
133
|
+
},
|
|
109
134
|
notify: {
|
|
110
135
|
last_notify: lastNotify,
|
|
111
136
|
last_openclaw_triggered_sync: lastOpenclawSync,
|
|
@@ -130,14 +155,6 @@ async function collectTrackerDiagnostics({
|
|
|
130
155
|
typeof openclawSessionProbe?.detail === "string"
|
|
131
156
|
? redactError(openclawSessionProbe.detail, home)
|
|
132
157
|
: null,
|
|
133
|
-
openclaw_hook_status: openclawLegacyProbe?.status || "unknown",
|
|
134
|
-
openclaw_hook_configured: Boolean(openclawLegacyProbe?.configured),
|
|
135
|
-
openclaw_hook_linked: Boolean(openclawLegacyProbe?.linked),
|
|
136
|
-
openclaw_hook_enabled: Boolean(openclawLegacyProbe?.enabled),
|
|
137
|
-
openclaw_hook_detail:
|
|
138
|
-
typeof openclawLegacyProbe?.detail === "string"
|
|
139
|
-
? redactError(openclawLegacyProbe.detail, home)
|
|
140
|
-
: null,
|
|
141
158
|
},
|
|
142
159
|
upload: {
|
|
143
160
|
last_success_at: lastSuccessAt,
|
|
@@ -194,6 +211,14 @@ async function safeStatSize(p) {
|
|
|
194
211
|
}
|
|
195
212
|
}
|
|
196
213
|
|
|
214
|
+
async function safeStat(p) {
|
|
215
|
+
try {
|
|
216
|
+
return await fs.stat(p);
|
|
217
|
+
} catch (_e) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
197
222
|
async function safeReadText(p) {
|
|
198
223
|
try {
|
|
199
224
|
return await fs.readFile(p, "utf8");
|
package/src/lib/doctor.js
CHANGED
|
@@ -313,8 +313,7 @@ function buildDiagnosticsChecks(diagnostics) {
|
|
|
313
313
|
notify.claude_hook_configured ||
|
|
314
314
|
notify.gemini_hook_configured ||
|
|
315
315
|
notify.opencode_plugin_configured ||
|
|
316
|
-
notify.openclaw_session_plugin_configured
|
|
317
|
-
notify.openclaw_hook_configured,
|
|
316
|
+
notify.openclaw_session_plugin_configured,
|
|
318
317
|
);
|
|
319
318
|
|
|
320
319
|
checks.push({
|
|
@@ -338,19 +337,6 @@ function buildDiagnosticsChecks(diagnostics) {
|
|
|
338
337
|
});
|
|
339
338
|
}
|
|
340
339
|
|
|
341
|
-
if (notify.openclaw_hook_status === "unreadable") {
|
|
342
|
-
checks.push({
|
|
343
|
-
id: "notify.openclaw_hook",
|
|
344
|
-
status: "warn",
|
|
345
|
-
detail: "OpenClaw hook config unreadable",
|
|
346
|
-
critical: false,
|
|
347
|
-
meta: {
|
|
348
|
-
status: notify.openclaw_hook_status,
|
|
349
|
-
detail: notify.openclaw_hook_detail || null,
|
|
350
|
-
},
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
|
|
354
340
|
const uploadError = diagnostics?.upload?.last_error || null;
|
|
355
341
|
checks.push({
|
|
356
342
|
id: "upload.last_error",
|
|
@@ -360,6 +346,29 @@ function buildDiagnosticsChecks(diagnostics) {
|
|
|
360
346
|
meta: { last_error: uploadError ? uploadError.message || null : null },
|
|
361
347
|
});
|
|
362
348
|
|
|
349
|
+
const opencode = diagnostics?.opencode || {};
|
|
350
|
+
const sqliteStatus =
|
|
351
|
+
typeof opencode.sqlite_status === "string" && opencode.sqlite_status.trim()
|
|
352
|
+
? opencode.sqlite_status.trim()
|
|
353
|
+
: "never_checked";
|
|
354
|
+
let opencodeStatus = "warn";
|
|
355
|
+
if (sqliteStatus === "ok") opencodeStatus = "ok";
|
|
356
|
+
else if (sqliteStatus === "missing-sqlite3" || sqliteStatus === "query-failed") {
|
|
357
|
+
opencodeStatus = "fail";
|
|
358
|
+
}
|
|
359
|
+
checks.push({
|
|
360
|
+
id: "opencode.sqlite_support",
|
|
361
|
+
status: opencodeStatus,
|
|
362
|
+
detail: `OpenCode SQLite reader ${sqliteStatus}`,
|
|
363
|
+
critical: false,
|
|
364
|
+
meta: {
|
|
365
|
+
sqlite_status: sqliteStatus,
|
|
366
|
+
sqlite_db_present: Boolean(opencode.sqlite_db_present),
|
|
367
|
+
sqlite_last_checked_at: opencode.sqlite_last_checked_at || null,
|
|
368
|
+
sqlite_error_code: opencode.sqlite_error_code || null,
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
|
|
363
372
|
return checks;
|
|
364
373
|
}
|
|
365
374
|
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
let sdkModulePromise = null;
|
|
4
|
+
|
|
5
|
+
async function loadInsforgeSdk() {
|
|
6
|
+
if (!sdkModulePromise) {
|
|
7
|
+
sdkModulePromise = import("@insforge/sdk").catch((err) => {
|
|
8
|
+
sdkModulePromise = null;
|
|
9
|
+
const wrapped = new Error("Missing dependency @insforge/sdk. Please reinstall vibeusage.");
|
|
10
|
+
wrapped.cause = err;
|
|
11
|
+
throw wrapped;
|
|
12
|
+
});
|
|
10
13
|
}
|
|
14
|
+
return sdkModulePromise;
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
function getAnonKey({ env = process.env } = {}) {
|
|
@@ -45,9 +49,9 @@ function createTimeoutFetch(baseFetch) {
|
|
|
45
49
|
};
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
function createInsforgeClient({ baseUrl, accessToken } = {}) {
|
|
52
|
+
async function createInsforgeClient({ baseUrl, accessToken } = {}) {
|
|
49
53
|
if (!baseUrl) throw new Error("Missing baseUrl");
|
|
50
|
-
const { createClient } = loadInsforgeSdk();
|
|
54
|
+
const { createClient } = await loadInsforgeSdk();
|
|
51
55
|
const anonKey = getAnonKey();
|
|
52
56
|
return createClient({
|
|
53
57
|
baseUrl,
|
|
@@ -8,7 +8,6 @@ const {
|
|
|
8
8
|
buildGeminiHookCommand,
|
|
9
9
|
} = require("../gemini-config");
|
|
10
10
|
const { resolveOpencodeConfigDir } = require("../opencode-config");
|
|
11
|
-
const { resolveOpenclawHookPaths } = require("../openclaw-hook");
|
|
12
11
|
const { resolveOpenclawSessionPluginPaths } = require("../openclaw-session-plugin");
|
|
13
12
|
const { resolveTrackerPaths } = require("../tracker-paths");
|
|
14
13
|
|
|
@@ -63,11 +62,6 @@ async function createIntegrationContext({
|
|
|
63
62
|
trackerDir: resolvedTrackerPaths.trackerDir,
|
|
64
63
|
env,
|
|
65
64
|
}),
|
|
66
|
-
openclawLegacy: resolveOpenclawHookPaths({
|
|
67
|
-
home,
|
|
68
|
-
trackerDir: resolvedTrackerPaths.trackerDir,
|
|
69
|
-
env,
|
|
70
|
-
}),
|
|
71
65
|
};
|
|
72
66
|
}
|
|
73
67
|
|
|
@@ -5,7 +5,6 @@ const claude = require("./claude");
|
|
|
5
5
|
const gemini = require("./gemini");
|
|
6
6
|
const opencode = require("./opencode");
|
|
7
7
|
const openclawSession = require("./openclaw-session");
|
|
8
|
-
const openclawLegacy = require("./openclaw-legacy");
|
|
9
8
|
|
|
10
9
|
const INTEGRATIONS = [
|
|
11
10
|
codex,
|
|
@@ -14,7 +13,6 @@ const INTEGRATIONS = [
|
|
|
14
13
|
gemini,
|
|
15
14
|
opencode,
|
|
16
15
|
openclawSession,
|
|
17
|
-
openclawLegacy,
|
|
18
16
|
];
|
|
19
17
|
|
|
20
18
|
function listIntegrations() {
|
|
@@ -3,6 +3,7 @@ const path = require("node:path");
|
|
|
3
3
|
const fs = require("node:fs/promises");
|
|
4
4
|
const fssync = require("node:fs");
|
|
5
5
|
const cp = require("node:child_process");
|
|
6
|
+
const { pathToFileURL } = require("node:url");
|
|
6
7
|
|
|
7
8
|
const OPENCLAW_SESSION_PLUGIN_ID = "openclaw-session-sync";
|
|
8
9
|
const OPENCLAW_SESSION_PLUGIN_DIRNAME = "openclaw-plugin";
|
|
@@ -103,7 +104,6 @@ async function ensureOpenclawSessionPluginFiles({
|
|
|
103
104
|
buildSessionPluginIndex({
|
|
104
105
|
trackerDir,
|
|
105
106
|
packageName,
|
|
106
|
-
openclawHome: openclawHome || path.join(os.homedir(), ".openclaw"),
|
|
107
107
|
}),
|
|
108
108
|
"utf8",
|
|
109
109
|
);
|
|
@@ -337,144 +337,58 @@ function buildSessionPluginMeta() {
|
|
|
337
337
|
)}\n`;
|
|
338
338
|
}
|
|
339
339
|
|
|
340
|
-
function buildSessionPluginIndex({ trackerDir
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
340
|
+
function buildSessionPluginIndex({ trackerDir }) {
|
|
341
|
+
const ledgerModuleUrl = pathToFileURL(
|
|
342
|
+
path.join(trackerDir, "app", "src", "lib", "openclaw-usage-ledger.js"),
|
|
343
|
+
).href;
|
|
344
344
|
|
|
345
345
|
return (
|
|
346
|
-
`import
|
|
347
|
-
`import path from 'node:path';\n` +
|
|
348
|
-
`import cp from 'node:child_process';\n` +
|
|
346
|
+
`import { appendOpenclawUsageEvent } from ${JSON.stringify(ledgerModuleUrl)};\n` +
|
|
349
347
|
`\n` +
|
|
350
348
|
`const trackerDir = ${JSON.stringify(trackerDir)};\n` +
|
|
351
|
-
`const trackerBinPath = ${JSON.stringify(trackerBinPath)};\n` +
|
|
352
|
-
`const fallbackPkg = ${JSON.stringify(fallbackPkg)};\n` +
|
|
353
|
-
`const openclawHome = ${JSON.stringify(safeOpenclawHome)};\n` +
|
|
354
|
-
`const depsMarkerPath = path.join(trackerDir, 'app', 'node_modules', '@insforge', 'sdk', 'package.json');\n` +
|
|
355
|
-
`const triggerStatePath = path.join(trackerDir, 'openclaw.session-sync.trigger-state.json');\n` +
|
|
356
|
-
`const SESSION_TRIGGER_THROTTLE_MS = 15_000;\n` +
|
|
357
349
|
`\n` +
|
|
358
350
|
`export default function register(api) {\n` +
|
|
359
|
-
` api.on('
|
|
351
|
+
` api.on('llm_output', async (event, ctx) => {\n` +
|
|
360
352
|
` try {\n` +
|
|
361
|
-
` const
|
|
362
|
-
` if (!
|
|
363
|
-
|
|
364
|
-
` const agentId = normalize(ctx && ctx.agentId) || parseAgentId(sessionKey);\n` +
|
|
365
|
-
` if (!agentId) return;\n` +
|
|
366
|
-
`\n` +
|
|
367
|
-
` const sessionInfo = resolveSessionInfo(agentId, sessionKey);\n` +
|
|
368
|
-
` const sessionId = normalize(sessionInfo && sessionInfo.sessionId);\n` +
|
|
369
|
-
` if (!sessionId) return;\n` +
|
|
370
|
-
`\n` +
|
|
371
|
-
` if (!allowTrigger('agent_end', agentId, sessionId)) return;\n` +
|
|
372
|
-
`\n` +
|
|
373
|
-
` spawnSync({\n` +
|
|
374
|
-
` args: ['sync', '--auto', '--from-openclaw'],\n` +
|
|
375
|
-
` env: buildSessionEnv({\n` +
|
|
376
|
-
` agentId,\n` +
|
|
377
|
-
` sessionId,\n` +
|
|
378
|
-
` sessionKey,\n` +
|
|
379
|
-
` sessionEntry: sessionInfo && sessionInfo.entry\n` +
|
|
380
|
-
` })\n` +
|
|
381
|
-
` });\n` +
|
|
382
|
-
` } catch (_) {}\n` +
|
|
383
|
-
` });\n` +
|
|
384
|
-
`\n` +
|
|
385
|
-
` api.on('gateway_start', async () => {\n` +
|
|
386
|
-
` try {\n` +
|
|
387
|
-
` if (!allowTrigger('gateway_start', 'gateway', 'startup')) return;\n` +
|
|
388
|
-
` spawnSync({ args: ['sync', '--auto'] });\n` +
|
|
389
|
-
` } catch (_) {}\n` +
|
|
390
|
-
` });\n` +
|
|
391
|
-
`\n` +
|
|
392
|
-
` api.on('gateway_stop', async () => {\n` +
|
|
393
|
-
` try {\n` +
|
|
394
|
-
` if (!allowTrigger('gateway_stop', 'gateway', 'stop')) return;\n` +
|
|
395
|
-
` spawnSync({ args: ['sync', '--auto'] });\n` +
|
|
353
|
+
` const payload = buildPayload(event, ctx);\n` +
|
|
354
|
+
` if (!payload) return;\n` +
|
|
355
|
+
` await appendOpenclawUsageEvent({ trackerDir, payload });\n` +
|
|
396
356
|
` } catch (_) {}\n` +
|
|
397
357
|
` });\n` +
|
|
398
358
|
`}\n` +
|
|
399
359
|
`\n` +
|
|
400
|
-
`function
|
|
401
|
-
` const
|
|
402
|
-
`
|
|
403
|
-
` const argv = Array.isArray(args) && args.length > 0 ? args : ['sync', '--auto'];\n` +
|
|
404
|
-
` const cmd = hasLocalRuntime && hasLocalDeps\n` +
|
|
405
|
-
` ? [process.execPath, trackerBinPath, ...argv]\n` +
|
|
406
|
-
` : ['npx', '--yes', fallbackPkg, ...argv];\n` +
|
|
407
|
-
` const child = cp.spawn(cmd[0], cmd.slice(1), {\n` +
|
|
408
|
-
` detached: true,\n` +
|
|
409
|
-
` stdio: 'ignore',\n` +
|
|
410
|
-
` env: { ...process.env, ...env }\n` +
|
|
411
|
-
` });\n` +
|
|
412
|
-
` child.unref();\n` +
|
|
413
|
-
`}\n` +
|
|
414
|
-
`\n` +
|
|
415
|
-
`function buildSessionEnv({ agentId, sessionId, sessionKey, sessionEntry }) {\n` +
|
|
416
|
-
` const out = {\n` +
|
|
417
|
-
` VIBEUSAGE_OPENCLAW_AGENT_ID: agentId,\n` +
|
|
418
|
-
` VIBEUSAGE_OPENCLAW_PREV_SESSION_ID: sessionId,\n` +
|
|
419
|
-
` VIBEUSAGE_OPENCLAW_HOME: openclawHome\n` +
|
|
420
|
-
` };\n` +
|
|
421
|
-
` const key = normalize(sessionKey);\n` +
|
|
422
|
-
` if (key) out.VIBEUSAGE_OPENCLAW_SESSION_KEY = key;\n` +
|
|
423
|
-
` const prevTotalTokens = toNonNegativeInt(sessionEntry && sessionEntry.totalTokens);\n` +
|
|
424
|
-
` const prevInputTokens = toNonNegativeInt(sessionEntry && sessionEntry.inputTokens);\n` +
|
|
425
|
-
` const prevOutputTokens = toNonNegativeInt(sessionEntry && sessionEntry.outputTokens);\n` +
|
|
426
|
-
` const prevModel = normalize(sessionEntry && sessionEntry.model);\n` +
|
|
427
|
-
` const prevUpdatedAt = toIso(sessionEntry && sessionEntry.updatedAt);\n` +
|
|
428
|
-
` if (prevTotalTokens != null) out.VIBEUSAGE_OPENCLAW_PREV_TOTAL_TOKENS = String(prevTotalTokens);\n` +
|
|
429
|
-
` if (prevInputTokens != null) out.VIBEUSAGE_OPENCLAW_PREV_INPUT_TOKENS = String(prevInputTokens);\n` +
|
|
430
|
-
` if (prevOutputTokens != null) out.VIBEUSAGE_OPENCLAW_PREV_OUTPUT_TOKENS = String(prevOutputTokens);\n` +
|
|
431
|
-
` if (prevModel) out.VIBEUSAGE_OPENCLAW_PREV_MODEL = prevModel;\n` +
|
|
432
|
-
` if (prevUpdatedAt) out.VIBEUSAGE_OPENCLAW_PREV_UPDATED_AT = prevUpdatedAt;\n` +
|
|
433
|
-
` return out;\n` +
|
|
434
|
-
`}\n` +
|
|
360
|
+
`function buildPayload(event, ctx) {\n` +
|
|
361
|
+
` const usage = normalizeUsage(event);\n` +
|
|
362
|
+
` if (!usage) return null;\n` +
|
|
435
363
|
`\n` +
|
|
436
|
-
`
|
|
437
|
-
`
|
|
438
|
-
` if (!key) return null;\n` +
|
|
439
|
-
` const sessionsPath = path.join(openclawHome, 'agents', agentId, 'sessions', 'sessions.json');\n` +
|
|
440
|
-
` try {\n` +
|
|
441
|
-
` const raw = fs.readFileSync(sessionsPath, 'utf8');\n` +
|
|
442
|
-
` const parsed = JSON.parse(raw);\n` +
|
|
443
|
-
` if (!parsed || typeof parsed !== 'object') return null;\n` +
|
|
444
|
-
` const entry = parsed[key];\n` +
|
|
445
|
-
` if (!entry || typeof entry !== 'object') return null;\n` +
|
|
446
|
-
` return {\n` +
|
|
447
|
-
` sessionKey: key,\n` +
|
|
448
|
-
` sessionId: normalize(entry.sessionId),\n` +
|
|
449
|
-
` entry\n` +
|
|
450
|
-
` };\n` +
|
|
451
|
-
` } catch (_) {}\n` +
|
|
452
|
-
` return null;\n` +
|
|
453
|
-
`}\n` +
|
|
364
|
+
` const sessionKey = normalize(ctx && ctx.sessionKey);\n` +
|
|
365
|
+
` if (!sessionKey) return null;\n` +
|
|
454
366
|
`\n` +
|
|
455
|
-
`
|
|
456
|
-
`
|
|
457
|
-
`
|
|
458
|
-
`
|
|
459
|
-
`
|
|
367
|
+
` return {\n` +
|
|
368
|
+
` emittedAt: normalizeIso(event && (event.emittedAt || event.timestamp)) || new Date().toISOString(),\n` +
|
|
369
|
+
` source: 'openclaw',\n` +
|
|
370
|
+
` agentId: normalize(ctx && ctx.agentId),\n` +
|
|
371
|
+
` sessionKey,\n` +
|
|
372
|
+
` provider: normalize(event && event.provider) || normalize(ctx && ctx.provider),\n` +
|
|
373
|
+
` model: normalize(event && event.model) || normalize(ctx && ctx.model),\n` +
|
|
374
|
+
` channel: normalize(ctx && ctx.channel),\n` +
|
|
375
|
+
` chatType: normalize(ctx && ctx.chatType),\n` +
|
|
376
|
+
` trigger: normalize(ctx && ctx.trigger) || 'llm_output',\n` +
|
|
377
|
+
` ...usage\n` +
|
|
378
|
+
` };\n` +
|
|
460
379
|
`}\n` +
|
|
461
380
|
`\n` +
|
|
462
|
-
`function
|
|
463
|
-
` const
|
|
464
|
-
` const
|
|
465
|
-
`
|
|
466
|
-
`
|
|
467
|
-
`
|
|
468
|
-
`
|
|
469
|
-
`
|
|
470
|
-
`
|
|
471
|
-
`
|
|
472
|
-
`
|
|
473
|
-
` try {\n` +
|
|
474
|
-
` fs.mkdirSync(path.dirname(triggerStatePath), { recursive: true });\n` +
|
|
475
|
-
` fs.writeFileSync(triggerStatePath, JSON.stringify(state), 'utf8');\n` +
|
|
476
|
-
` } catch (_) {}\n` +
|
|
477
|
-
` return true;\n` +
|
|
381
|
+
`function normalizeUsage(event) {\n` +
|
|
382
|
+
` const usage = event && typeof event.usage === 'object' ? event.usage : event || {};\n` +
|
|
383
|
+
` const normalized = {\n` +
|
|
384
|
+
` inputTokens: toNonNegativeInt(usage.inputTokens ?? usage.input_tokens ?? usage.input),\n` +
|
|
385
|
+
` cachedInputTokens: toNonNegativeInt(usage.cachedInputTokens ?? usage.cached_input_tokens ?? usage.cacheRead ?? 0) + toNonNegativeInt(usage.cacheWrite ?? 0),\n` +
|
|
386
|
+
` outputTokens: toNonNegativeInt(usage.outputTokens ?? usage.output_tokens ?? usage.output),\n` +
|
|
387
|
+
` reasoningOutputTokens: toNonNegativeInt(usage.reasoningOutputTokens ?? usage.reasoning_output_tokens),\n` +
|
|
388
|
+
` totalTokens: toNonNegativeInt(usage.totalTokens ?? usage.total_tokens)\n` +
|
|
389
|
+
` };\n` +
|
|
390
|
+
` const sum = normalized.inputTokens + normalized.cachedInputTokens + normalized.outputTokens + normalized.reasoningOutputTokens + normalized.totalTokens;\n` +
|
|
391
|
+
` return sum > 0 ? normalized : null;\n` +
|
|
478
392
|
`}\n` +
|
|
479
393
|
`\n` +
|
|
480
394
|
`function normalize(v) {\n` +
|
|
@@ -483,22 +397,18 @@ function buildSessionPluginIndex({ trackerDir, packageName = "vibeusage", opencl
|
|
|
483
397
|
` return s.length > 0 ? s : null;\n` +
|
|
484
398
|
`}\n` +
|
|
485
399
|
`\n` +
|
|
486
|
-
`function
|
|
487
|
-
` const
|
|
488
|
-
` if (!
|
|
489
|
-
`
|
|
400
|
+
`function normalizeIso(v) {\n` +
|
|
401
|
+
` const s = normalize(v);\n` +
|
|
402
|
+
` if (!s) return null;\n` +
|
|
403
|
+
` const ms = Date.parse(s);\n` +
|
|
404
|
+
` if (!Number.isFinite(ms)) return null;\n` +
|
|
405
|
+
` return new Date(ms).toISOString();\n` +
|
|
490
406
|
`}\n` +
|
|
491
407
|
`\n` +
|
|
492
|
-
`function
|
|
493
|
-
`
|
|
494
|
-
`
|
|
495
|
-
`
|
|
496
|
-
` }\n` +
|
|
497
|
-
` const n = Number(v);\n` +
|
|
498
|
-
` if (!Number.isFinite(n) || n <= 0) return null;\n` +
|
|
499
|
-
` const ms = n < 1e12 ? Math.floor(n * 1000) : Math.floor(n);\n` +
|
|
500
|
-
` const d = new Date(ms);\n` +
|
|
501
|
-
` return Number.isNaN(d.getTime()) ? null : d.toISOString();\n` +
|
|
408
|
+
`function toNonNegativeInt(v) {\n` +
|
|
409
|
+
` const n = Number(v || 0);\n` +
|
|
410
|
+
` if (!Number.isFinite(n) || n < 0) return 0;\n` +
|
|
411
|
+
` return Math.floor(n);\n` +
|
|
502
412
|
`}\n`
|
|
503
413
|
);
|
|
504
414
|
}
|