@opendatalabs/connect 0.11.6 → 0.12.0-canary.7843ac9
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 +312 -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 +494 -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;AAmEjE,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;AAgmDD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAWpD;AAssCD,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, getActiveTelemetrySession, 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,155 @@ 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("needs_input") ||
|
|
511
|
+
value.includes("needs input") ||
|
|
512
|
+
value.includes("input required") ||
|
|
513
|
+
value.includes("manual step"))
|
|
514
|
+
return "needs_input";
|
|
515
|
+
if (value.includes("prompt_cancelled") || value.includes("cancelled"))
|
|
516
|
+
return "prompt_cancelled";
|
|
517
|
+
if (value.includes("personal_server_unavailable") ||
|
|
518
|
+
value.includes("personal server unavailable"))
|
|
519
|
+
return "personal_server_unavailable";
|
|
520
|
+
if (value.includes("auth expired"))
|
|
521
|
+
return "auth_expired";
|
|
522
|
+
if (value.includes("auth"))
|
|
523
|
+
return "auth_failed";
|
|
524
|
+
if (value.includes("setup"))
|
|
525
|
+
return "setup_required";
|
|
526
|
+
if (value.includes("timeout") || value.includes("timed out"))
|
|
527
|
+
return "timeout";
|
|
528
|
+
if (value.includes("network"))
|
|
529
|
+
return "network_error";
|
|
530
|
+
if (value.includes("runtime"))
|
|
531
|
+
return "runtime_error";
|
|
532
|
+
if (value.includes("connector"))
|
|
533
|
+
return "connector_unavailable";
|
|
534
|
+
if (value.includes("ingest"))
|
|
535
|
+
return "ingest_failed";
|
|
536
|
+
}
|
|
537
|
+
return "unknown";
|
|
538
|
+
}
|
|
539
|
+
async function runCommandWithTelemetry(context, action) {
|
|
540
|
+
const session = await createCliTelemetrySession({
|
|
541
|
+
...context,
|
|
542
|
+
options: {
|
|
543
|
+
json: Boolean(context.options.json),
|
|
544
|
+
noInput: Boolean(context.options.noInput),
|
|
545
|
+
quiet: Boolean(context.options.quiet),
|
|
546
|
+
detach: Boolean(context.options.detach),
|
|
547
|
+
ipc: Boolean(context.options.ipc),
|
|
548
|
+
},
|
|
549
|
+
localOnly: context.localOnly,
|
|
550
|
+
});
|
|
551
|
+
setActiveTelemetrySession(session);
|
|
552
|
+
await flushTelemetryOutbox();
|
|
553
|
+
try {
|
|
554
|
+
const exitCode = await action();
|
|
555
|
+
session.markCommandResult({ exitCode });
|
|
556
|
+
return exitCode;
|
|
557
|
+
}
|
|
558
|
+
catch (error) {
|
|
559
|
+
session.markCommandResult({
|
|
560
|
+
exitCode: 1,
|
|
561
|
+
errorClass: classifyCommandFailure(error),
|
|
562
|
+
});
|
|
563
|
+
throw error;
|
|
564
|
+
}
|
|
565
|
+
finally {
|
|
566
|
+
await session.persist();
|
|
567
|
+
await session.flush();
|
|
568
|
+
setActiveTelemetrySession(null);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
async function runLongRunningCommandWithTelemetry(context, action) {
|
|
572
|
+
const session = await createCliTelemetrySession({
|
|
573
|
+
...context,
|
|
574
|
+
options: {
|
|
575
|
+
json: Boolean(context.options.json),
|
|
576
|
+
noInput: Boolean(context.options.noInput),
|
|
577
|
+
quiet: Boolean(context.options.quiet),
|
|
578
|
+
detach: Boolean(context.options.detach),
|
|
579
|
+
ipc: Boolean(context.options.ipc),
|
|
580
|
+
},
|
|
581
|
+
});
|
|
582
|
+
setActiveTelemetrySession(session);
|
|
583
|
+
await flushTelemetryOutbox();
|
|
584
|
+
session.trackCustomEvent("mcp_started");
|
|
585
|
+
session.markCommandResult({ exitCode: 0, outcome: "started" });
|
|
586
|
+
await session.persist();
|
|
587
|
+
await session.flush();
|
|
588
|
+
try {
|
|
589
|
+
await action();
|
|
590
|
+
return 0;
|
|
591
|
+
}
|
|
592
|
+
finally {
|
|
593
|
+
setActiveTelemetrySession(null);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
async function runTelemetryStatus(options) {
|
|
597
|
+
const status = await getTelemetryStatus();
|
|
598
|
+
const endpointHost = (() => {
|
|
599
|
+
try {
|
|
600
|
+
return new URL(status.endpoint).host;
|
|
601
|
+
}
|
|
602
|
+
catch {
|
|
603
|
+
return status.endpoint;
|
|
604
|
+
}
|
|
605
|
+
})();
|
|
606
|
+
if (options.json) {
|
|
607
|
+
process.stdout.write(`${JSON.stringify(status)}\n`);
|
|
608
|
+
return 0;
|
|
609
|
+
}
|
|
610
|
+
const emit = createEmitter(options);
|
|
611
|
+
emit.title("Telemetry");
|
|
612
|
+
emit.blank();
|
|
613
|
+
emit.keyValue("Enabled", status.enabled ? "yes" : "no");
|
|
614
|
+
emit.keyValue("Mode", status.mode);
|
|
615
|
+
emit.keyValue("Reason", status.reason.replaceAll("_", " "));
|
|
616
|
+
emit.keyValue("Endpoint", endpointHost);
|
|
617
|
+
emit.keyValue("Queued", String(status.queuedBatches));
|
|
618
|
+
emit.detail("Collected data stays local. Remote telemetry only includes small operational events.");
|
|
619
|
+
if (status.enabled) {
|
|
620
|
+
emit.detail(`Disable with: ${emit.code("vana telemetry disable")}`);
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
emit.detail(`Enable with: ${emit.code("vana telemetry enable")}`);
|
|
624
|
+
}
|
|
625
|
+
if (process.env.VANA_TELEMETRY_DEBUG === "1") {
|
|
626
|
+
emit.detail(`Debug mode is active via ${emit.code("VANA_TELEMETRY_DEBUG=1")}. Events print to stderr and are not uploaded.`);
|
|
627
|
+
}
|
|
628
|
+
if (process.env.VANA_TELEMETRY_DISABLED === "1") {
|
|
629
|
+
emit.detail(`Telemetry is currently overridden by ${emit.code("VANA_TELEMETRY_DISABLED=1")}.`);
|
|
630
|
+
}
|
|
631
|
+
return 0;
|
|
632
|
+
}
|
|
633
|
+
async function runTelemetryEnable(options) {
|
|
634
|
+
await setTelemetryEnabled(true);
|
|
635
|
+
if (options.json) {
|
|
636
|
+
process.stdout.write(`${JSON.stringify({ enabled: true })}\n`);
|
|
637
|
+
return 0;
|
|
638
|
+
}
|
|
639
|
+
const emit = createEmitter(options);
|
|
640
|
+
emit.success("Telemetry enabled.");
|
|
641
|
+
if (process.env.VANA_TELEMETRY_DISABLED === "1") {
|
|
642
|
+
emit.detail(`The current shell still disables uploads via ${emit.code("VANA_TELEMETRY_DISABLED=1")}.`);
|
|
643
|
+
}
|
|
644
|
+
return 0;
|
|
645
|
+
}
|
|
646
|
+
async function runTelemetryDisable(options) {
|
|
647
|
+
await setTelemetryEnabled(false);
|
|
648
|
+
if (options.json) {
|
|
649
|
+
process.stdout.write(`${JSON.stringify({ enabled: false })}\n`);
|
|
650
|
+
return 0;
|
|
651
|
+
}
|
|
652
|
+
const emit = createEmitter(options);
|
|
653
|
+
emit.success("Telemetry disabled.");
|
|
654
|
+
return 0;
|
|
655
|
+
}
|
|
460
656
|
async function runConnect(rawSource, options) {
|
|
461
657
|
const source = rawSource.toLowerCase();
|
|
462
658
|
const runtime = new ManagedPlaywrightRuntime();
|
|
@@ -510,7 +706,18 @@ async function runConnect(rawSource, options) {
|
|
|
510
706
|
}
|
|
511
707
|
process.stderr.write("\n");
|
|
512
708
|
}
|
|
513
|
-
|
|
709
|
+
trackActiveTelemetryEvent("runtime_install_started", { source });
|
|
710
|
+
let installResult;
|
|
711
|
+
try {
|
|
712
|
+
installResult = await runtime.ensureInstalled(Boolean(options.yes));
|
|
713
|
+
}
|
|
714
|
+
catch (error) {
|
|
715
|
+
trackActiveTelemetryEvent("runtime_install_failed", {
|
|
716
|
+
source,
|
|
717
|
+
errorClass: classifyCommandFailure(error),
|
|
718
|
+
});
|
|
719
|
+
throw error;
|
|
720
|
+
}
|
|
514
721
|
setupLogPath = installResult.logPath;
|
|
515
722
|
emit.event({
|
|
516
723
|
type: "setup-complete",
|
|
@@ -599,6 +806,13 @@ async function runConnect(rawSource, options) {
|
|
|
599
806
|
}
|
|
600
807
|
}
|
|
601
808
|
if (fetched.updated && fetched.previousVersion) {
|
|
809
|
+
trackActiveTelemetryEvent("connector_update_applied", {
|
|
810
|
+
source,
|
|
811
|
+
metadata: {
|
|
812
|
+
previousVersion: fetched.previousVersion,
|
|
813
|
+
connectorVersion: fetched.version,
|
|
814
|
+
},
|
|
815
|
+
});
|
|
602
816
|
renderer?.detail(`Updated connector (${fetched.previousVersion} → ${fetched.version}).`);
|
|
603
817
|
}
|
|
604
818
|
fetchLogPath = fetched.logPath;
|
|
@@ -613,6 +827,10 @@ async function runConnect(rawSource, options) {
|
|
|
613
827
|
connectorPath: resolution.connectorPath,
|
|
614
828
|
logPath: fetched.logPath,
|
|
615
829
|
});
|
|
830
|
+
trackActiveTelemetryEvent("connector_version_detected", {
|
|
831
|
+
source: resolution.source,
|
|
832
|
+
connectorVersion: fetched.version,
|
|
833
|
+
});
|
|
616
834
|
// --- Phase 3: Pre-connection validation (silent) ---
|
|
617
835
|
const profilePath = path.join(getBrowserProfilesDir(), `${path.basename(resolution.connectorPath, path.extname(resolution.connectorPath))}`);
|
|
618
836
|
if (sourceDetails?.authMode === "legacy" &&
|
|
@@ -2196,7 +2414,11 @@ async function runCollectAll(options) {
|
|
|
2196
2414
|
async function runServerSync(options) {
|
|
2197
2415
|
const emit = createEmitter(options);
|
|
2198
2416
|
const target = await detectPersonalServerTarget();
|
|
2417
|
+
trackActiveTelemetryEvent("server_sync_started");
|
|
2199
2418
|
if (target.state !== "available") {
|
|
2419
|
+
trackActiveTelemetryEvent("server_sync_failed", {
|
|
2420
|
+
errorClass: "personal_server_unavailable",
|
|
2421
|
+
});
|
|
2200
2422
|
if (options.json) {
|
|
2201
2423
|
process.stdout.write(`${JSON.stringify({
|
|
2202
2424
|
error: "personal_server_unavailable",
|
|
@@ -2209,7 +2431,16 @@ async function runServerSync(options) {
|
|
|
2209
2431
|
return 1;
|
|
2210
2432
|
}
|
|
2211
2433
|
const syncResult = await syncPendingSources(target, "manual");
|
|
2434
|
+
const storedScopeCount = syncResult.sourceResults.reduce((total, entry) => total +
|
|
2435
|
+
(entry.scopeResults?.filter((scopeResult) => scopeResult.status === "stored").length ?? 0), 0);
|
|
2436
|
+
const failedScopeCount = syncResult.sourceResults.reduce((total, entry) => total +
|
|
2437
|
+
(entry.scopeResults?.filter((scopeResult) => scopeResult.status === "failed").length ?? 0), 0);
|
|
2212
2438
|
if (syncResult.sourceResults.length === 0) {
|
|
2439
|
+
trackActiveTelemetryEvent("server_sync_completed", {
|
|
2440
|
+
storedScopeCount: 0,
|
|
2441
|
+
failedScopeCount: 0,
|
|
2442
|
+
metadata: { syncedSources: 0 },
|
|
2443
|
+
});
|
|
2213
2444
|
if (options.json) {
|
|
2214
2445
|
process.stdout.write(`${JSON.stringify({ message: "No pending datasets to sync.", syncedCount: 0 })}\n`);
|
|
2215
2446
|
}
|
|
@@ -2250,6 +2481,11 @@ async function runServerSync(options) {
|
|
|
2250
2481
|
emit.next("vana server sync");
|
|
2251
2482
|
}
|
|
2252
2483
|
}
|
|
2484
|
+
trackActiveTelemetryEvent("server_sync_completed", {
|
|
2485
|
+
storedScopeCount,
|
|
2486
|
+
failedScopeCount,
|
|
2487
|
+
metadata: { syncedSources: syncResult.syncedCount },
|
|
2488
|
+
});
|
|
2253
2489
|
return 0;
|
|
2254
2490
|
}
|
|
2255
2491
|
async function runServerData(scope, options) {
|
|
@@ -2414,6 +2650,7 @@ function createEmitter(options) {
|
|
|
2414
2650
|
const renderer = createHumanRenderer();
|
|
2415
2651
|
return {
|
|
2416
2652
|
event(event) {
|
|
2653
|
+
getActiveTelemetrySession()?.trackCliEvent(event);
|
|
2417
2654
|
if (options.json) {
|
|
2418
2655
|
process.stdout.write(`${JSON.stringify(event)}\n`);
|
|
2419
2656
|
}
|
|
@@ -3560,6 +3797,7 @@ async function runDetached(command, source, options) {
|
|
|
3560
3797
|
stdio: ["ignore", logFd, logFd],
|
|
3561
3798
|
env: { ...process.env, VANA_DETACHED: "1" },
|
|
3562
3799
|
});
|
|
3800
|
+
trackActiveTelemetryEvent("detached_run_spawned", { source });
|
|
3563
3801
|
child.unref();
|
|
3564
3802
|
fs.closeSync(logFd);
|
|
3565
3803
|
// Write session file
|
|
@@ -3764,6 +4002,9 @@ async function runScheduleAdd(interval, options) {
|
|
|
3764
4002
|
emit.detail(`launchctl load "${LAUNCHD_PLIST_PATH}"`);
|
|
3765
4003
|
return 1;
|
|
3766
4004
|
}
|
|
4005
|
+
trackActiveTelemetryEvent("schedule_added", {
|
|
4006
|
+
metadata: { interval: intervalLabel, mechanism: "launchd" },
|
|
4007
|
+
});
|
|
3767
4008
|
if (options.json) {
|
|
3768
4009
|
process.stdout.write(`${JSON.stringify({ ok: true, interval: intervalLabel, mechanism: "launchd", plistPath: LAUNCHD_PLIST_PATH })}\n`);
|
|
3769
4010
|
return 0;
|
|
@@ -3804,6 +4045,9 @@ async function runScheduleAdd(interval, options) {
|
|
|
3804
4045
|
emit.detail(entry);
|
|
3805
4046
|
return 1;
|
|
3806
4047
|
}
|
|
4048
|
+
trackActiveTelemetryEvent("schedule_added", {
|
|
4049
|
+
metadata: { interval: intervalLabel, mechanism: "cron" },
|
|
4050
|
+
});
|
|
3807
4051
|
if (options.json) {
|
|
3808
4052
|
process.stdout.write(`${JSON.stringify({ ok: true, interval: intervalLabel, mechanism: "cron" })}\n`);
|
|
3809
4053
|
return 0;
|
|
@@ -3845,6 +4089,9 @@ async function runScheduleAdd(interval, options) {
|
|
|
3845
4089
|
emit.detail(`schtasks /Create /TN "${WINDOWS_TASK_NAME}" /TR "${trCmd}" /SC DAILY /ST 09:00 /F`);
|
|
3846
4090
|
return 1;
|
|
3847
4091
|
}
|
|
4092
|
+
trackActiveTelemetryEvent("schedule_added", {
|
|
4093
|
+
metadata: { interval: intervalLabel, mechanism: "schtasks" },
|
|
4094
|
+
});
|
|
3848
4095
|
if (options.json) {
|
|
3849
4096
|
process.stdout.write(`${JSON.stringify({ ok: true, interval: intervalLabel, mechanism: "schtasks" })}\n`);
|
|
3850
4097
|
return 0;
|
|
@@ -3962,6 +4209,9 @@ async function runScheduleRemove(options) {
|
|
|
3962
4209
|
// Already unloaded
|
|
3963
4210
|
}
|
|
3964
4211
|
await fsp.unlink(LAUNCHD_PLIST_PATH);
|
|
4212
|
+
trackActiveTelemetryEvent("schedule_removed", {
|
|
4213
|
+
metadata: { mechanism: "launchd" },
|
|
4214
|
+
});
|
|
3965
4215
|
if (options.json) {
|
|
3966
4216
|
process.stdout.write(`${JSON.stringify({ ok: true, removed: true })}\n`);
|
|
3967
4217
|
return 0;
|
|
@@ -3987,6 +4237,9 @@ async function runScheduleRemove(options) {
|
|
|
3987
4237
|
input: `${filtered.trimEnd()}\n`,
|
|
3988
4238
|
encoding: "utf8",
|
|
3989
4239
|
});
|
|
4240
|
+
trackActiveTelemetryEvent("schedule_removed", {
|
|
4241
|
+
metadata: { mechanism: "cron" },
|
|
4242
|
+
});
|
|
3990
4243
|
if (options.json) {
|
|
3991
4244
|
process.stdout.write(`${JSON.stringify({ ok: true, removed: true })}\n`);
|
|
3992
4245
|
return 0;
|
|
@@ -4004,6 +4257,9 @@ async function runScheduleRemove(options) {
|
|
|
4004
4257
|
execSync(`schtasks /Delete /TN "${WINDOWS_TASK_NAME}" /F`, {
|
|
4005
4258
|
stdio: "ignore",
|
|
4006
4259
|
});
|
|
4260
|
+
trackActiveTelemetryEvent("schedule_removed", {
|
|
4261
|
+
metadata: { mechanism: "schtasks" },
|
|
4262
|
+
});
|
|
4007
4263
|
if (options.json) {
|
|
4008
4264
|
process.stdout.write(`${JSON.stringify({ ok: true, removed: true })}\n`);
|
|
4009
4265
|
return 0;
|
|
@@ -4158,6 +4414,9 @@ async function runSkillInstall(name, options) {
|
|
|
4158
4414
|
const emit = createEmitter(options);
|
|
4159
4415
|
try {
|
|
4160
4416
|
const { installedPath } = await installSkill(name);
|
|
4417
|
+
trackActiveTelemetryEvent("skill_installed", {
|
|
4418
|
+
metadata: { skillName: name },
|
|
4419
|
+
});
|
|
4161
4420
|
if (options.json) {
|
|
4162
4421
|
process.stdout.write(`${JSON.stringify({ ok: true, id: name, installedPath })}\n`);
|
|
4163
4422
|
return 0;
|