@opendatalabs/connect 0.11.6 → 0.12.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.
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +291 -53
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/telemetry.d.ts +76 -0
- package/dist/cli/telemetry.d.ts.map +1 -0
- package/dist/cli/telemetry.js +444 -0
- package/dist/cli/telemetry.js.map +1 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/paths.d.ts +2 -0
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/paths.js +6 -0
- package/dist/core/paths.js.map +1 -1
- package/dist/core/state-store.d.ts +2 -0
- package/dist/core/state-store.d.ts.map +1 -1
- package/dist/core/state-store.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAwCA,OAAO,EAQL,YAAY,EAIb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EACV,UAAU,EAEV,gBAAgB,EAEhB,SAAS,EACT,YAAY,EACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAwCA,OAAO,EAQL,YAAY,EAIb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EACV,UAAU,EAEV,gBAAgB,EAEhB,SAAS,EACT,YAAY,EACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAkEjE,UAAU,cAAc;IACtB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED,UAAU,iBAAiB;IACzB,CAAC,MAAM,EAAE,MAAM,GAAG;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,QAAQ,CAAC;KACnD,CAAC;CACH;AA2BD,KAAK,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAehF,wBAAsB,MAAM,CAAC,IAAI,WAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAmoBjE;AA0kDD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAWpD;AAqsCD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,cAAmB,GAC1B,MAAM,CAER;AAkBD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CASrD;AAuGD,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,CACnB,MAAM,EACN,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAC5D,EACD,QAAQ,GAAE,iBAAsB,GAC/B,OAAO,CAAC,YAAY,EAAE,CAAC,CAoEzB;AAED,wBAAsB,2BAA2B,IAAI,OAAO,CAC1D,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CACxC,CAyBA;AA6LD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,YAAY,EAAE,EACvB,YAAY,GAAE,cAAmB,EACjC,OAAO,GAAE,SAAS,CAAC,SAAS,CAAe,EAC3C,gBAAgB,GAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAM,GAC5E,MAAM,EAAE,CA+HV;AAED,wBAAgB,qBAAqB,CACnC,iBAAiB,EACb;IACE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,QAAQ,CAAC;CACnD,GACD,IAAI,GACJ,SAAS,EACb,cAAc,EAAE,MAAM,GACrB,MAAM,EAAE,CAgBV;AAED,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,KAAK,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC,EACF,eAAe,EAAE,KAAK,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,QAAQ,CAAC;CACnD,CAAC,GACD,MAAM,EAAE,CAmBV;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,YAAY,GAAE,cAAmB,GAChC,MAAM,EAAE,CAQV;AAmCD,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAqB7E;AA2CD,wBAAgB,aAAa,IAAI,MAAM,CA2BtC;AAED,wBAAgB,aAAa,CAAC,OAAO,SAAkB,GAAG,QAAQ,GAAG,QAAQ,CAc5E;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,SAAmB,GAC1B,gBAAgB,CA+BlB;AAMD,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,gBAAgB,EAC/B,QAAQ,SAAmB,GAC1B,MAAM,GAAG,IAAI,CAQf;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAWzE;AAED,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,gBAAgB,EAC/B,OAAO,EAAE,UAAU,GAClB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAoCxC;AAaD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC3C,cAAc,CAEhB;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,KAAK,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,QAAQ,CAAC;CACnD,CAAC,GACD,iBAAiB,CAYnB;AAID,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,YAAY,GAAG;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;CAClB,CA2DA;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,UAAU,CAQxE;AAqED,wBAAsB,mBAAmB,+BAQxC;AAYD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,YAAY,GAClB,MAAM,CAgBR;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAiB/D;AAqCD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA6B7D;AAeD,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CAOrC;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B;IAAE,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAoD5B;AA6BD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUrD;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE;IACJ,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB,EACD,KAAK,EAAE;IACL,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB,GACA,MAAM,CAaR;AAsBD,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,YAAY,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,GACtD,OAAO,CAOT"}
|
package/dist/cli/index.js
CHANGED
|
@@ -35,6 +35,7 @@ import { listAvailableSkills, installSkill, readInstalledSkills, } from "../skil
|
|
|
35
35
|
import { queryStatus, querySources, queryDataList, queryDataShow, queryDoctor, } from "./queries.js";
|
|
36
36
|
import { checkForUpdate, readUpdateCheck, isNewerVersion, } from "./update-check.js";
|
|
37
37
|
import { loadCredentials, saveCredentials, clearCredentials, isExpired, formatAddress, formatExpiresIn, getAuthTarget, resolvePersonalServerUrl, runDeviceCodeFlow, runSelfHostedLoginFlow, } from "./auth.js";
|
|
38
|
+
import { createCliTelemetrySession, flushTelemetryOutbox, getTelemetryStatus, setActiveTelemetrySession, setTelemetryEnabled, trackActiveTelemetryEvent, } from "./telemetry.js";
|
|
38
39
|
function cleanDescription(desc) {
|
|
39
40
|
return desc
|
|
40
41
|
.replace(/ using Playwright browser automation\.?/i, ".")
|
|
@@ -53,6 +54,12 @@ export async function runCli(argv = process.argv) {
|
|
|
53
54
|
const parsedOptions = extractGlobalOptions(normalizedArgv);
|
|
54
55
|
const cliVersion = getCliVersion();
|
|
55
56
|
const installMethod = getCliInstallMethod();
|
|
57
|
+
const telemetryBaseContext = {
|
|
58
|
+
cliVersion,
|
|
59
|
+
channel: getCliChannel(cliVersion),
|
|
60
|
+
installMethod,
|
|
61
|
+
options: parsedOptions,
|
|
62
|
+
};
|
|
56
63
|
// Non-blocking update check — compute suppression flags early
|
|
57
64
|
const shouldNotify = !parsedOptions.json &&
|
|
58
65
|
process.stdout.isTTY &&
|
|
@@ -108,17 +115,18 @@ More:
|
|
|
108
115
|
.description("Print CLI version")
|
|
109
116
|
.option("--json", "Output machine-readable JSON")
|
|
110
117
|
.action(async () => {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "version" }, async () => {
|
|
119
|
+
if (parsedOptions.json) {
|
|
120
|
+
process.stdout.write(`${JSON.stringify({
|
|
121
|
+
cliVersion,
|
|
122
|
+
channel: getCliChannel(cliVersion),
|
|
123
|
+
installMethod: getCliInstallMethod(),
|
|
124
|
+
})}\n`);
|
|
125
|
+
return 0;
|
|
126
|
+
}
|
|
127
|
+
process.stdout.write(`${cliVersion} (${getCliChannel(cliVersion)}, ${formatInstallMethodLabel(getCliInstallMethod()).toLowerCase()})\n`);
|
|
128
|
+
return 0;
|
|
129
|
+
});
|
|
122
130
|
});
|
|
123
131
|
const connectCommand = program
|
|
124
132
|
.command("connect [source]")
|
|
@@ -130,13 +138,14 @@ More:
|
|
|
130
138
|
.option("--quiet", "Reduce non-essential output")
|
|
131
139
|
.option("--detach", "Run in the background")
|
|
132
140
|
.action(async (source) => {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
141
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "connect", source }, async () => {
|
|
142
|
+
if (parsedOptions.detach && source) {
|
|
143
|
+
return runDetached("connect", source, parsedOptions);
|
|
144
|
+
}
|
|
145
|
+
return source
|
|
146
|
+
? runConnect(source, parsedOptions)
|
|
147
|
+
: runConnectEntry(parsedOptions);
|
|
148
|
+
});
|
|
140
149
|
});
|
|
141
150
|
connectCommand.addHelpText("after", `
|
|
142
151
|
Examples:
|
|
@@ -150,9 +159,9 @@ Examples:
|
|
|
150
159
|
.description("List supported sources, or show detail for one source")
|
|
151
160
|
.option("--json", "Output machine-readable JSON")
|
|
152
161
|
.action(async (source) => {
|
|
153
|
-
process.exitCode = source
|
|
154
|
-
?
|
|
155
|
-
:
|
|
162
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "sources", source }, async () => source
|
|
163
|
+
? runSourceDetail(source, parsedOptions)
|
|
164
|
+
: runList(parsedOptions));
|
|
156
165
|
});
|
|
157
166
|
sourcesCommand.addHelpText("after", `
|
|
158
167
|
Examples:
|
|
@@ -171,13 +180,14 @@ Examples:
|
|
|
171
180
|
.option("--detach", "Run in the background")
|
|
172
181
|
.option("--all", "Collect from all connected sources")
|
|
173
182
|
.action(async (source) => {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
183
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "collect", source }, async () => {
|
|
184
|
+
if (parsedOptions.detach && source) {
|
|
185
|
+
return runDetached("collect", source, parsedOptions);
|
|
186
|
+
}
|
|
187
|
+
return source
|
|
188
|
+
? runCollect(source, parsedOptions)
|
|
189
|
+
: runCollectAll(parsedOptions);
|
|
190
|
+
});
|
|
181
191
|
});
|
|
182
192
|
collectCommand.addHelpText("after", `
|
|
183
193
|
Examples:
|
|
@@ -190,7 +200,7 @@ Examples:
|
|
|
190
200
|
.description("Show runtime and Personal Server status")
|
|
191
201
|
.option("--json", "Output machine-readable JSON")
|
|
192
202
|
.action(async () => {
|
|
193
|
-
process.exitCode = await runStatus(parsedOptions);
|
|
203
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "status" }, async () => runStatus(parsedOptions));
|
|
194
204
|
});
|
|
195
205
|
statusCommand.addHelpText("after", `
|
|
196
206
|
Examples:
|
|
@@ -202,7 +212,7 @@ Examples:
|
|
|
202
212
|
.description("Inspect local CLI, runtime, and install health")
|
|
203
213
|
.option("--json", "Output machine-readable JSON")
|
|
204
214
|
.action(async () => {
|
|
205
|
-
process.exitCode = await runDoctor(parsedOptions);
|
|
215
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "doctor" }, async () => runDoctor(parsedOptions));
|
|
206
216
|
});
|
|
207
217
|
doctorCommand.addHelpText("after", `
|
|
208
218
|
Examples:
|
|
@@ -215,7 +225,7 @@ Examples:
|
|
|
215
225
|
.option("--json", "Output machine-readable JSON")
|
|
216
226
|
.option("--yes", "Approve safe setup prompts automatically")
|
|
217
227
|
.action(async () => {
|
|
218
|
-
process.exitCode = await runSetup(parsedOptions);
|
|
228
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "setup" }, async () => runSetup(parsedOptions));
|
|
219
229
|
});
|
|
220
230
|
setupCommand.addHelpText("after", `
|
|
221
231
|
Examples:
|
|
@@ -240,7 +250,7 @@ Examples:
|
|
|
240
250
|
.description("List locally available collected datasets")
|
|
241
251
|
.option("--json", "Output machine-readable JSON")
|
|
242
252
|
.action(async () => {
|
|
243
|
-
process.exitCode = await runDataList(parsedOptions);
|
|
253
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "data", subcommand: "list" }, async () => runDataList(parsedOptions));
|
|
244
254
|
});
|
|
245
255
|
dataListCommand.addHelpText("after", `
|
|
246
256
|
Examples:
|
|
@@ -252,7 +262,12 @@ Examples:
|
|
|
252
262
|
.description("Show a collected dataset")
|
|
253
263
|
.option("--json", "Output machine-readable JSON")
|
|
254
264
|
.action(async (source) => {
|
|
255
|
-
process.exitCode = await
|
|
265
|
+
process.exitCode = await runCommandWithTelemetry({
|
|
266
|
+
...telemetryBaseContext,
|
|
267
|
+
command: "data",
|
|
268
|
+
subcommand: "show",
|
|
269
|
+
source,
|
|
270
|
+
}, async () => runDataShow(source, parsedOptions));
|
|
256
271
|
});
|
|
257
272
|
dataShowCommand.addHelpText("after", `
|
|
258
273
|
Examples:
|
|
@@ -264,7 +279,12 @@ Examples:
|
|
|
264
279
|
.description("Print the local path for a collected dataset")
|
|
265
280
|
.option("--json", "Output machine-readable JSON")
|
|
266
281
|
.action(async (source) => {
|
|
267
|
-
process.exitCode = await
|
|
282
|
+
process.exitCode = await runCommandWithTelemetry({
|
|
283
|
+
...telemetryBaseContext,
|
|
284
|
+
command: "data",
|
|
285
|
+
subcommand: "path",
|
|
286
|
+
source,
|
|
287
|
+
}, async () => runDataPath(source, parsedOptions));
|
|
268
288
|
});
|
|
269
289
|
dataPathCommand.addHelpText("after", `
|
|
270
290
|
Examples:
|
|
@@ -276,7 +296,7 @@ Examples:
|
|
|
276
296
|
.description("Inspect stored connector run logs")
|
|
277
297
|
.option("--json", "Output machine-readable JSON")
|
|
278
298
|
.action(async (source) => {
|
|
279
|
-
process.exitCode = await runLogs(source, parsedOptions);
|
|
299
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "logs", source }, async () => runLogs(source, parsedOptions));
|
|
280
300
|
});
|
|
281
301
|
logsCommand.addHelpText("after", `
|
|
282
302
|
Examples:
|
|
@@ -296,62 +316,89 @@ Examples:
|
|
|
296
316
|
vana server clear-url
|
|
297
317
|
`);
|
|
298
318
|
server.action(async () => {
|
|
299
|
-
process.exitCode = await runServerStatus(parsedOptions);
|
|
319
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "server", subcommand: "status" }, async () => runServerStatus(parsedOptions));
|
|
300
320
|
});
|
|
301
321
|
server
|
|
302
322
|
.command("status")
|
|
303
323
|
.description("Show Personal Server status")
|
|
304
324
|
.option("--json", "Output machine-readable JSON")
|
|
305
325
|
.action(async () => {
|
|
306
|
-
process.exitCode = await runServerStatus(parsedOptions);
|
|
326
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "server", subcommand: "status" }, async () => runServerStatus(parsedOptions));
|
|
307
327
|
});
|
|
308
328
|
server
|
|
309
329
|
.command("set-url <url>")
|
|
310
330
|
.description("Save a Personal Server URL")
|
|
311
331
|
.option("--json", "Output machine-readable JSON")
|
|
312
332
|
.action(async (url) => {
|
|
313
|
-
process.exitCode = await runServerSetUrl(url, parsedOptions);
|
|
333
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "server", subcommand: "set-url" }, async () => runServerSetUrl(url, parsedOptions));
|
|
314
334
|
});
|
|
315
335
|
server
|
|
316
336
|
.command("clear-url")
|
|
317
337
|
.description("Remove the saved Personal Server URL")
|
|
318
338
|
.option("--json", "Output machine-readable JSON")
|
|
319
339
|
.action(async () => {
|
|
320
|
-
process.exitCode = await runServerClearUrl(parsedOptions);
|
|
340
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "server", subcommand: "clear-url" }, async () => runServerClearUrl(parsedOptions));
|
|
321
341
|
});
|
|
322
342
|
server
|
|
323
343
|
.command("sync")
|
|
324
344
|
.description("Sync all local-only datasets to your Personal Server")
|
|
325
345
|
.option("--json", "Output machine-readable JSON")
|
|
326
346
|
.action(async () => {
|
|
327
|
-
process.exitCode = await runServerSync(parsedOptions);
|
|
347
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "server", subcommand: "sync" }, async () => runServerSync(parsedOptions));
|
|
328
348
|
});
|
|
329
349
|
server
|
|
330
350
|
.command("data [scope]")
|
|
331
351
|
.description("List scopes stored in your Personal Server")
|
|
332
352
|
.option("--json", "Output machine-readable JSON")
|
|
333
353
|
.action(async (scope) => {
|
|
334
|
-
process.exitCode = await runServerData(scope, parsedOptions);
|
|
354
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "server", subcommand: "data" }, async () => runServerData(scope, parsedOptions));
|
|
335
355
|
});
|
|
336
356
|
program
|
|
337
357
|
.command("login")
|
|
338
358
|
.description("Log in to your Vana account or a self-hosted Personal Server")
|
|
339
359
|
.option("-s, --server <url>", "Self-hosted Personal Server URL")
|
|
340
360
|
.action(async (loginOptions) => {
|
|
341
|
-
process.exitCode = await runLogin(parsedOptions, loginOptions.server);
|
|
361
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "login" }, async () => runLogin(parsedOptions, loginOptions.server));
|
|
342
362
|
});
|
|
343
363
|
program
|
|
344
364
|
.command("logout")
|
|
345
365
|
.description("Log out and remove saved credentials")
|
|
346
366
|
.action(async () => {
|
|
347
|
-
process.exitCode = await runLogout(parsedOptions);
|
|
367
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "logout" }, async () => runLogout(parsedOptions));
|
|
368
|
+
});
|
|
369
|
+
const telemetry = program
|
|
370
|
+
.command("telemetry")
|
|
371
|
+
.description("Inspect and manage CLI telemetry");
|
|
372
|
+
telemetry.action(async () => {
|
|
373
|
+
process.exitCode = await runTelemetryStatus(parsedOptions);
|
|
374
|
+
});
|
|
375
|
+
telemetry
|
|
376
|
+
.command("status")
|
|
377
|
+
.description("Show telemetry state")
|
|
378
|
+
.option("--json", "Output machine-readable JSON")
|
|
379
|
+
.action(async () => {
|
|
380
|
+
process.exitCode = await runTelemetryStatus(parsedOptions);
|
|
381
|
+
});
|
|
382
|
+
telemetry
|
|
383
|
+
.command("enable")
|
|
384
|
+
.description("Enable telemetry")
|
|
385
|
+
.action(async () => {
|
|
386
|
+
process.exitCode = await runTelemetryEnable(parsedOptions);
|
|
387
|
+
});
|
|
388
|
+
telemetry
|
|
389
|
+
.command("disable")
|
|
390
|
+
.description("Disable telemetry")
|
|
391
|
+
.action(async () => {
|
|
392
|
+
process.exitCode = await runTelemetryDisable(parsedOptions);
|
|
348
393
|
});
|
|
349
394
|
program
|
|
350
395
|
.command("mcp")
|
|
351
396
|
.description("Start MCP server for agent integration")
|
|
352
397
|
.action(async () => {
|
|
353
|
-
|
|
354
|
-
|
|
398
|
+
process.exitCode = await runLongRunningCommandWithTelemetry({ ...telemetryBaseContext, command: "mcp" }, async () => {
|
|
399
|
+
const { startMcpServer } = await import("./mcp-server.js");
|
|
400
|
+
await startMcpServer();
|
|
401
|
+
});
|
|
355
402
|
});
|
|
356
403
|
const skill = program
|
|
357
404
|
.command("skills")
|
|
@@ -364,26 +411,26 @@ Examples:
|
|
|
364
411
|
vana skills show connect-data
|
|
365
412
|
`);
|
|
366
413
|
skill.action(async () => {
|
|
367
|
-
process.exitCode = await runSkillsGuidedPicker(parsedOptions);
|
|
414
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "skills" }, async () => runSkillsGuidedPicker(parsedOptions));
|
|
368
415
|
});
|
|
369
416
|
skill
|
|
370
417
|
.command("list")
|
|
371
418
|
.description("List available agent skills")
|
|
372
419
|
.option("--json", "Output as JSON")
|
|
373
420
|
.action(async () => {
|
|
374
|
-
process.exitCode = await runSkillList(parsedOptions);
|
|
421
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "skills", subcommand: "list" }, async () => runSkillList(parsedOptions));
|
|
375
422
|
});
|
|
376
423
|
skill
|
|
377
424
|
.command("install <name>")
|
|
378
425
|
.description("Install a skill for your agent")
|
|
379
426
|
.action(async (name) => {
|
|
380
|
-
process.exitCode = await runSkillInstall(name, parsedOptions);
|
|
427
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "skills", subcommand: "install" }, async () => runSkillInstall(name, parsedOptions));
|
|
381
428
|
});
|
|
382
429
|
skill
|
|
383
430
|
.command("show <name>")
|
|
384
431
|
.description("Show skill details")
|
|
385
432
|
.action(async (name) => {
|
|
386
|
-
process.exitCode = await runSkillShow(name, parsedOptions);
|
|
433
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "skills", subcommand: "show" }, async () => runSkillShow(name, parsedOptions));
|
|
387
434
|
});
|
|
388
435
|
// --- Schedule commands ---
|
|
389
436
|
const schedule = program
|
|
@@ -405,20 +452,20 @@ Examples:
|
|
|
405
452
|
.description("Add a scheduled collection")
|
|
406
453
|
.option("--every <interval>", "Collection interval (e.g. 24h, 12h, 1h)", "24h")
|
|
407
454
|
.action(async (opts) => {
|
|
408
|
-
process.exitCode = await runScheduleAdd(opts.every, parsedOptions);
|
|
455
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "schedule", subcommand: "add" }, async () => runScheduleAdd(opts.every, parsedOptions));
|
|
409
456
|
});
|
|
410
457
|
schedule
|
|
411
458
|
.command("list")
|
|
412
459
|
.description("Show scheduled tasks")
|
|
413
460
|
.option("--json", "Output machine-readable JSON")
|
|
414
461
|
.action(async () => {
|
|
415
|
-
process.exitCode = await runScheduleList(parsedOptions);
|
|
462
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "schedule", subcommand: "list" }, async () => runScheduleList(parsedOptions));
|
|
416
463
|
});
|
|
417
464
|
schedule
|
|
418
465
|
.command("remove")
|
|
419
466
|
.description("Remove the scheduled collection")
|
|
420
467
|
.action(async () => {
|
|
421
|
-
process.exitCode = await runScheduleRemove(parsedOptions);
|
|
468
|
+
process.exitCode = await runCommandWithTelemetry({ ...telemetryBaseContext, command: "schedule", subcommand: "remove" }, async () => runScheduleRemove(parsedOptions));
|
|
422
469
|
});
|
|
423
470
|
try {
|
|
424
471
|
await program.parseAsync(normalizedArgv);
|
|
@@ -457,6 +504,139 @@ Examples:
|
|
|
457
504
|
}
|
|
458
505
|
return Number(process.exitCode ?? 0);
|
|
459
506
|
}
|
|
507
|
+
function classifyCommandFailure(error) {
|
|
508
|
+
if (error instanceof Error) {
|
|
509
|
+
const value = error.message.toLowerCase();
|
|
510
|
+
if (value.includes("auth"))
|
|
511
|
+
return "auth_failed";
|
|
512
|
+
if (value.includes("setup"))
|
|
513
|
+
return "setup_required";
|
|
514
|
+
if (value.includes("runtime"))
|
|
515
|
+
return "runtime_error";
|
|
516
|
+
if (value.includes("connector"))
|
|
517
|
+
return "connector_unavailable";
|
|
518
|
+
if (value.includes("ingest"))
|
|
519
|
+
return "ingest_failed";
|
|
520
|
+
}
|
|
521
|
+
return "unknown";
|
|
522
|
+
}
|
|
523
|
+
async function runCommandWithTelemetry(context, action) {
|
|
524
|
+
const session = await createCliTelemetrySession({
|
|
525
|
+
...context,
|
|
526
|
+
options: {
|
|
527
|
+
json: Boolean(context.options.json),
|
|
528
|
+
noInput: Boolean(context.options.noInput),
|
|
529
|
+
quiet: Boolean(context.options.quiet),
|
|
530
|
+
detach: Boolean(context.options.detach),
|
|
531
|
+
ipc: Boolean(context.options.ipc),
|
|
532
|
+
},
|
|
533
|
+
localOnly: context.localOnly,
|
|
534
|
+
});
|
|
535
|
+
setActiveTelemetrySession(session);
|
|
536
|
+
await flushTelemetryOutbox();
|
|
537
|
+
try {
|
|
538
|
+
const exitCode = await action();
|
|
539
|
+
session.markCommandResult({ exitCode });
|
|
540
|
+
return exitCode;
|
|
541
|
+
}
|
|
542
|
+
catch (error) {
|
|
543
|
+
session.markCommandResult({
|
|
544
|
+
exitCode: 1,
|
|
545
|
+
errorClass: classifyCommandFailure(error),
|
|
546
|
+
});
|
|
547
|
+
throw error;
|
|
548
|
+
}
|
|
549
|
+
finally {
|
|
550
|
+
await session.persist();
|
|
551
|
+
await session.flush();
|
|
552
|
+
setActiveTelemetrySession(null);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
async function runLongRunningCommandWithTelemetry(context, action) {
|
|
556
|
+
const session = await createCliTelemetrySession({
|
|
557
|
+
...context,
|
|
558
|
+
options: {
|
|
559
|
+
json: Boolean(context.options.json),
|
|
560
|
+
noInput: Boolean(context.options.noInput),
|
|
561
|
+
quiet: Boolean(context.options.quiet),
|
|
562
|
+
detach: Boolean(context.options.detach),
|
|
563
|
+
ipc: Boolean(context.options.ipc),
|
|
564
|
+
},
|
|
565
|
+
});
|
|
566
|
+
setActiveTelemetrySession(session);
|
|
567
|
+
await flushTelemetryOutbox();
|
|
568
|
+
session.trackCustomEvent("mcp_started");
|
|
569
|
+
session.markCommandResult({ exitCode: 0, outcome: "started" });
|
|
570
|
+
await session.persist();
|
|
571
|
+
await session.flush();
|
|
572
|
+
try {
|
|
573
|
+
await action();
|
|
574
|
+
return 0;
|
|
575
|
+
}
|
|
576
|
+
finally {
|
|
577
|
+
setActiveTelemetrySession(null);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
async function runTelemetryStatus(options) {
|
|
581
|
+
const status = await getTelemetryStatus();
|
|
582
|
+
const endpointHost = (() => {
|
|
583
|
+
try {
|
|
584
|
+
return new URL(status.endpoint).host;
|
|
585
|
+
}
|
|
586
|
+
catch {
|
|
587
|
+
return status.endpoint;
|
|
588
|
+
}
|
|
589
|
+
})();
|
|
590
|
+
if (options.json) {
|
|
591
|
+
process.stdout.write(`${JSON.stringify(status)}\n`);
|
|
592
|
+
return 0;
|
|
593
|
+
}
|
|
594
|
+
const emit = createEmitter(options);
|
|
595
|
+
emit.title("Telemetry");
|
|
596
|
+
emit.blank();
|
|
597
|
+
emit.keyValue("Enabled", status.enabled ? "yes" : "no");
|
|
598
|
+
emit.keyValue("Mode", status.mode);
|
|
599
|
+
emit.keyValue("Reason", status.reason.replaceAll("_", " "));
|
|
600
|
+
emit.keyValue("Endpoint", endpointHost);
|
|
601
|
+
emit.keyValue("Queued", String(status.queuedBatches));
|
|
602
|
+
emit.detail("Collected data stays local. Remote telemetry only includes small operational events.");
|
|
603
|
+
if (status.enabled) {
|
|
604
|
+
emit.detail(`Disable with: ${emit.code("vana telemetry disable")}`);
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
emit.detail(`Enable with: ${emit.code("vana telemetry enable")}`);
|
|
608
|
+
}
|
|
609
|
+
if (process.env.VANA_TELEMETRY_DEBUG === "1") {
|
|
610
|
+
emit.detail(`Debug mode is active via ${emit.code("VANA_TELEMETRY_DEBUG=1")}. Events print to stderr and are not uploaded.`);
|
|
611
|
+
}
|
|
612
|
+
if (process.env.VANA_TELEMETRY_DISABLED === "1") {
|
|
613
|
+
emit.detail(`Telemetry is currently overridden by ${emit.code("VANA_TELEMETRY_DISABLED=1")}.`);
|
|
614
|
+
}
|
|
615
|
+
return 0;
|
|
616
|
+
}
|
|
617
|
+
async function runTelemetryEnable(options) {
|
|
618
|
+
await setTelemetryEnabled(true);
|
|
619
|
+
if (options.json) {
|
|
620
|
+
process.stdout.write(`${JSON.stringify({ enabled: true })}\n`);
|
|
621
|
+
return 0;
|
|
622
|
+
}
|
|
623
|
+
const emit = createEmitter(options);
|
|
624
|
+
emit.success("Telemetry enabled.");
|
|
625
|
+
if (process.env.VANA_TELEMETRY_DISABLED === "1") {
|
|
626
|
+
emit.detail(`The current shell still disables uploads via ${emit.code("VANA_TELEMETRY_DISABLED=1")}.`);
|
|
627
|
+
}
|
|
628
|
+
return 0;
|
|
629
|
+
}
|
|
630
|
+
async function runTelemetryDisable(options) {
|
|
631
|
+
await setTelemetryEnabled(false);
|
|
632
|
+
if (options.json) {
|
|
633
|
+
process.stdout.write(`${JSON.stringify({ enabled: false })}\n`);
|
|
634
|
+
return 0;
|
|
635
|
+
}
|
|
636
|
+
const emit = createEmitter(options);
|
|
637
|
+
emit.success("Telemetry disabled.");
|
|
638
|
+
return 0;
|
|
639
|
+
}
|
|
460
640
|
async function runConnect(rawSource, options) {
|
|
461
641
|
const source = rawSource.toLowerCase();
|
|
462
642
|
const runtime = new ManagedPlaywrightRuntime();
|
|
@@ -510,7 +690,18 @@ async function runConnect(rawSource, options) {
|
|
|
510
690
|
}
|
|
511
691
|
process.stderr.write("\n");
|
|
512
692
|
}
|
|
513
|
-
|
|
693
|
+
trackActiveTelemetryEvent("runtime_install_started", { source });
|
|
694
|
+
let installResult;
|
|
695
|
+
try {
|
|
696
|
+
installResult = await runtime.ensureInstalled(Boolean(options.yes));
|
|
697
|
+
}
|
|
698
|
+
catch (error) {
|
|
699
|
+
trackActiveTelemetryEvent("runtime_install_failed", {
|
|
700
|
+
source,
|
|
701
|
+
errorClass: classifyCommandFailure(error),
|
|
702
|
+
});
|
|
703
|
+
throw error;
|
|
704
|
+
}
|
|
514
705
|
setupLogPath = installResult.logPath;
|
|
515
706
|
emit.event({
|
|
516
707
|
type: "setup-complete",
|
|
@@ -599,6 +790,13 @@ async function runConnect(rawSource, options) {
|
|
|
599
790
|
}
|
|
600
791
|
}
|
|
601
792
|
if (fetched.updated && fetched.previousVersion) {
|
|
793
|
+
trackActiveTelemetryEvent("connector_update_applied", {
|
|
794
|
+
source,
|
|
795
|
+
metadata: {
|
|
796
|
+
previousVersion: fetched.previousVersion,
|
|
797
|
+
connectorVersion: fetched.version,
|
|
798
|
+
},
|
|
799
|
+
});
|
|
602
800
|
renderer?.detail(`Updated connector (${fetched.previousVersion} → ${fetched.version}).`);
|
|
603
801
|
}
|
|
604
802
|
fetchLogPath = fetched.logPath;
|
|
@@ -2196,7 +2394,11 @@ async function runCollectAll(options) {
|
|
|
2196
2394
|
async function runServerSync(options) {
|
|
2197
2395
|
const emit = createEmitter(options);
|
|
2198
2396
|
const target = await detectPersonalServerTarget();
|
|
2397
|
+
trackActiveTelemetryEvent("server_sync_started");
|
|
2199
2398
|
if (target.state !== "available") {
|
|
2399
|
+
trackActiveTelemetryEvent("server_sync_failed", {
|
|
2400
|
+
errorClass: "personal_server_unavailable",
|
|
2401
|
+
});
|
|
2200
2402
|
if (options.json) {
|
|
2201
2403
|
process.stdout.write(`${JSON.stringify({
|
|
2202
2404
|
error: "personal_server_unavailable",
|
|
@@ -2209,7 +2411,16 @@ async function runServerSync(options) {
|
|
|
2209
2411
|
return 1;
|
|
2210
2412
|
}
|
|
2211
2413
|
const syncResult = await syncPendingSources(target, "manual");
|
|
2414
|
+
const storedScopeCount = syncResult.sourceResults.reduce((total, entry) => total +
|
|
2415
|
+
(entry.scopeResults?.filter((scopeResult) => scopeResult.status === "stored").length ?? 0), 0);
|
|
2416
|
+
const failedScopeCount = syncResult.sourceResults.reduce((total, entry) => total +
|
|
2417
|
+
(entry.scopeResults?.filter((scopeResult) => scopeResult.status === "failed").length ?? 0), 0);
|
|
2212
2418
|
if (syncResult.sourceResults.length === 0) {
|
|
2419
|
+
trackActiveTelemetryEvent("server_sync_completed", {
|
|
2420
|
+
storedScopeCount: 0,
|
|
2421
|
+
failedScopeCount: 0,
|
|
2422
|
+
metadata: { syncedSources: 0 },
|
|
2423
|
+
});
|
|
2213
2424
|
if (options.json) {
|
|
2214
2425
|
process.stdout.write(`${JSON.stringify({ message: "No pending datasets to sync.", syncedCount: 0 })}\n`);
|
|
2215
2426
|
}
|
|
@@ -2250,6 +2461,11 @@ async function runServerSync(options) {
|
|
|
2250
2461
|
emit.next("vana server sync");
|
|
2251
2462
|
}
|
|
2252
2463
|
}
|
|
2464
|
+
trackActiveTelemetryEvent("server_sync_completed", {
|
|
2465
|
+
storedScopeCount,
|
|
2466
|
+
failedScopeCount,
|
|
2467
|
+
metadata: { syncedSources: syncResult.syncedCount },
|
|
2468
|
+
});
|
|
2253
2469
|
return 0;
|
|
2254
2470
|
}
|
|
2255
2471
|
async function runServerData(scope, options) {
|
|
@@ -3560,6 +3776,7 @@ async function runDetached(command, source, options) {
|
|
|
3560
3776
|
stdio: ["ignore", logFd, logFd],
|
|
3561
3777
|
env: { ...process.env, VANA_DETACHED: "1" },
|
|
3562
3778
|
});
|
|
3779
|
+
trackActiveTelemetryEvent("detached_run_spawned", { source });
|
|
3563
3780
|
child.unref();
|
|
3564
3781
|
fs.closeSync(logFd);
|
|
3565
3782
|
// Write session file
|
|
@@ -3764,6 +3981,9 @@ async function runScheduleAdd(interval, options) {
|
|
|
3764
3981
|
emit.detail(`launchctl load "${LAUNCHD_PLIST_PATH}"`);
|
|
3765
3982
|
return 1;
|
|
3766
3983
|
}
|
|
3984
|
+
trackActiveTelemetryEvent("schedule_added", {
|
|
3985
|
+
metadata: { interval: intervalLabel, mechanism: "launchd" },
|
|
3986
|
+
});
|
|
3767
3987
|
if (options.json) {
|
|
3768
3988
|
process.stdout.write(`${JSON.stringify({ ok: true, interval: intervalLabel, mechanism: "launchd", plistPath: LAUNCHD_PLIST_PATH })}\n`);
|
|
3769
3989
|
return 0;
|
|
@@ -3804,6 +4024,9 @@ async function runScheduleAdd(interval, options) {
|
|
|
3804
4024
|
emit.detail(entry);
|
|
3805
4025
|
return 1;
|
|
3806
4026
|
}
|
|
4027
|
+
trackActiveTelemetryEvent("schedule_added", {
|
|
4028
|
+
metadata: { interval: intervalLabel, mechanism: "cron" },
|
|
4029
|
+
});
|
|
3807
4030
|
if (options.json) {
|
|
3808
4031
|
process.stdout.write(`${JSON.stringify({ ok: true, interval: intervalLabel, mechanism: "cron" })}\n`);
|
|
3809
4032
|
return 0;
|
|
@@ -3845,6 +4068,9 @@ async function runScheduleAdd(interval, options) {
|
|
|
3845
4068
|
emit.detail(`schtasks /Create /TN "${WINDOWS_TASK_NAME}" /TR "${trCmd}" /SC DAILY /ST 09:00 /F`);
|
|
3846
4069
|
return 1;
|
|
3847
4070
|
}
|
|
4071
|
+
trackActiveTelemetryEvent("schedule_added", {
|
|
4072
|
+
metadata: { interval: intervalLabel, mechanism: "schtasks" },
|
|
4073
|
+
});
|
|
3848
4074
|
if (options.json) {
|
|
3849
4075
|
process.stdout.write(`${JSON.stringify({ ok: true, interval: intervalLabel, mechanism: "schtasks" })}\n`);
|
|
3850
4076
|
return 0;
|
|
@@ -3962,6 +4188,9 @@ async function runScheduleRemove(options) {
|
|
|
3962
4188
|
// Already unloaded
|
|
3963
4189
|
}
|
|
3964
4190
|
await fsp.unlink(LAUNCHD_PLIST_PATH);
|
|
4191
|
+
trackActiveTelemetryEvent("schedule_removed", {
|
|
4192
|
+
metadata: { mechanism: "launchd" },
|
|
4193
|
+
});
|
|
3965
4194
|
if (options.json) {
|
|
3966
4195
|
process.stdout.write(`${JSON.stringify({ ok: true, removed: true })}\n`);
|
|
3967
4196
|
return 0;
|
|
@@ -3987,6 +4216,9 @@ async function runScheduleRemove(options) {
|
|
|
3987
4216
|
input: `${filtered.trimEnd()}\n`,
|
|
3988
4217
|
encoding: "utf8",
|
|
3989
4218
|
});
|
|
4219
|
+
trackActiveTelemetryEvent("schedule_removed", {
|
|
4220
|
+
metadata: { mechanism: "cron" },
|
|
4221
|
+
});
|
|
3990
4222
|
if (options.json) {
|
|
3991
4223
|
process.stdout.write(`${JSON.stringify({ ok: true, removed: true })}\n`);
|
|
3992
4224
|
return 0;
|
|
@@ -4004,6 +4236,9 @@ async function runScheduleRemove(options) {
|
|
|
4004
4236
|
execSync(`schtasks /Delete /TN "${WINDOWS_TASK_NAME}" /F`, {
|
|
4005
4237
|
stdio: "ignore",
|
|
4006
4238
|
});
|
|
4239
|
+
trackActiveTelemetryEvent("schedule_removed", {
|
|
4240
|
+
metadata: { mechanism: "schtasks" },
|
|
4241
|
+
});
|
|
4007
4242
|
if (options.json) {
|
|
4008
4243
|
process.stdout.write(`${JSON.stringify({ ok: true, removed: true })}\n`);
|
|
4009
4244
|
return 0;
|
|
@@ -4158,6 +4393,9 @@ async function runSkillInstall(name, options) {
|
|
|
4158
4393
|
const emit = createEmitter(options);
|
|
4159
4394
|
try {
|
|
4160
4395
|
const { installedPath } = await installSkill(name);
|
|
4396
|
+
trackActiveTelemetryEvent("skill_installed", {
|
|
4397
|
+
metadata: { skillName: name },
|
|
4398
|
+
});
|
|
4161
4399
|
if (options.json) {
|
|
4162
4400
|
process.stdout.write(`${JSON.stringify({ ok: true, id: name, installedPath })}\n`);
|
|
4163
4401
|
return 0;
|