@local-labs-jpollock/local-addon-nexus-ai 0.1.2 → 0.1.3
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/docs-site/docs/reference/telemetry-privacy.md +168 -0
- package/docs-site/mkdocs.yml +1 -0
- package/lib/cli/index.js +18 -2
- package/lib/cli/index.js.map +1 -1
- package/lib/cli/utils/telemetry.d.ts +27 -0
- package/lib/cli/utils/telemetry.d.ts.map +1 -0
- package/lib/cli/utils/telemetry.js +179 -0
- package/lib/cli/utils/telemetry.js.map +1 -0
- package/lib/main/telemetry/telemetry-config.d.ts.map +1 -1
- package/lib/main/telemetry/telemetry-config.js +9 -1
- package/lib/main/telemetry/telemetry-config.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/index.ts +15 -2
- package/src/cli/utils/telemetry.ts +161 -0
- package/src/main/telemetry/telemetry-config.ts +8 -1
- package/tests/unit/cli/telemetry.test.ts +311 -0
- package/tests/unit/telemetry/telemetry-config.test.ts +408 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Telemetry & Privacy
|
|
2
|
+
|
|
3
|
+
Nexus AI collects anonymous usage data to understand which features are used, identify common errors, and guide product decisions. This page explains exactly what is and isn't collected, how to opt out, and how the data is protected.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Opt-Out Model
|
|
8
|
+
|
|
9
|
+
Telemetry is **enabled by default** but you can opt out at any time. No account, login, or personal information is ever required or collected.
|
|
10
|
+
|
|
11
|
+
**Disable via CLI:**
|
|
12
|
+
```bash
|
|
13
|
+
nexus telemetry disable
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Disable via environment variable** (useful for CI/CD):
|
|
17
|
+
```bash
|
|
18
|
+
NEXUS_TELEMETRY=0 nexus ...
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Auto-disabled in CI environments** — Nexus AI detects `CI`, `GITHUB_ACTIONS`, `GITLAB_CI`, `TRAVIS`, `CIRCLECI`, `BUILDKITE`, and `JENKINS_URL` and disables telemetry automatically.
|
|
22
|
+
|
|
23
|
+
**Re-enable:**
|
|
24
|
+
```bash
|
|
25
|
+
nexus telemetry enable
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Check current status:**
|
|
29
|
+
```bash
|
|
30
|
+
nexus telemetry status
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## What Is Collected
|
|
36
|
+
|
|
37
|
+
### Tool Call Events
|
|
38
|
+
Recorded every time an MCP tool or CLI command is executed.
|
|
39
|
+
|
|
40
|
+
| Field | Example | Purpose |
|
|
41
|
+
|-------|---------|---------|
|
|
42
|
+
| `event_type` | `tool_call` | Event classification |
|
|
43
|
+
| `tool_name` | `wp_plugin_list` | Which feature is being used |
|
|
44
|
+
| `access_method` | `mcp` or `cli` | How it was invoked |
|
|
45
|
+
| `success` | `true` / `false` | Error rate tracking |
|
|
46
|
+
| `duration_ms` | `245` | Performance monitoring |
|
|
47
|
+
| `error_category` | `site_not_running` | Error pattern analysis |
|
|
48
|
+
| `timestamp` | ISO 8601 | Timing distribution |
|
|
49
|
+
|
|
50
|
+
### Health Check Events
|
|
51
|
+
Sent once per hour while Local is running.
|
|
52
|
+
|
|
53
|
+
| Field | Example | Purpose |
|
|
54
|
+
|-------|---------|---------|
|
|
55
|
+
| `event_type` | `health_check` | Event classification |
|
|
56
|
+
| `memory_mb` | `128.5` | Memory usage trends |
|
|
57
|
+
| `health_status` | `healthy` | System health signal |
|
|
58
|
+
| `active_sites` | `5` | Fleet size distribution |
|
|
59
|
+
|
|
60
|
+
### Identity Fields (on every event)
|
|
61
|
+
| Field | Example | Purpose |
|
|
62
|
+
|-------|---------|---------|
|
|
63
|
+
| `installation_id` | Random UUID | Group events per install |
|
|
64
|
+
| `session_id` | Random UUID | Group events per Local session |
|
|
65
|
+
| `addon_version` | `0.1.2` | Version adoption tracking |
|
|
66
|
+
| `os` | `darwin` | Platform breakdown |
|
|
67
|
+
| `node_version` | `v20.x` | Runtime compatibility |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## What Is Never Collected
|
|
72
|
+
|
|
73
|
+
- Site names, domains, or file paths
|
|
74
|
+
- WordPress content, posts, or page data
|
|
75
|
+
- Plugin names, theme names, or versions
|
|
76
|
+
- Arguments passed to tools
|
|
77
|
+
- Error messages or stack traces
|
|
78
|
+
- User identity, email, or account information
|
|
79
|
+
- API keys, tokens, or credentials
|
|
80
|
+
- WP Engine account details
|
|
81
|
+
|
|
82
|
+
### Permanently Excluded Tools
|
|
83
|
+
These tool categories are never transmitted, regardless of telemetry settings:
|
|
84
|
+
|
|
85
|
+
| Prefix | Reason |
|
|
86
|
+
|--------|--------|
|
|
87
|
+
| `wpe_*` | May reference WP Engine account identifiers |
|
|
88
|
+
| `wp_db_*` | Database operations may contain sensitive data |
|
|
89
|
+
| `wp_search_replace` | May contain site content |
|
|
90
|
+
| `wp_user_*` | User management operations |
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## How It Works
|
|
95
|
+
|
|
96
|
+
### Installation Identity
|
|
97
|
+
On first run, Nexus AI generates two values and stores them in:
|
|
98
|
+
```
|
|
99
|
+
~/Library/Application Support/Local/nexus-ai/config.json
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
- **`installationId`** — a random UUID that identifies this installation. Never tied to you personally.
|
|
103
|
+
- **`secretKey`** — a random 32-byte value used to sign outgoing events (see Authentication below).
|
|
104
|
+
|
|
105
|
+
These are generated once and reused across sessions. They are not shared with any third party.
|
|
106
|
+
|
|
107
|
+
### Local Event Queue (MCP only)
|
|
108
|
+
MCP telemetry (from AI tool invocations) is written to a local JSONL file before transmitting:
|
|
109
|
+
```
|
|
110
|
+
~/Library/Application Support/Local/nexus-ai/telemetry/events.jsonl
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
This file is capped at 10,000 events (oldest are pruned when the limit is reached). You can inspect it, clear it with `nexus telemetry clear`, or delete it manually.
|
|
114
|
+
|
|
115
|
+
CLI telemetry transmits directly to the analytics endpoint — it does not write to the local queue.
|
|
116
|
+
|
|
117
|
+
### Transmission
|
|
118
|
+
Events are sent individually to a Cloudflare Worker over HTTPS using fire-and-forget — transmission never blocks or delays addon operation. Failed transmissions are not retried.
|
|
119
|
+
|
|
120
|
+
**Endpoint:** `https://nexus-analytics.jeremy7746.workers.dev/v1/events`
|
|
121
|
+
|
|
122
|
+
### Request Authentication
|
|
123
|
+
Each request is signed with HMAC-SHA256 using the `secretKey` stored in `config.json`. This lets the server verify the event came from a legitimate Nexus AI installation without requiring any user account or login.
|
|
124
|
+
|
|
125
|
+
On first transmission, the secret key is sent to the server (via `X-Secret-Key` header) so it can be stored for future verification. Subsequent requests include only an `X-Signature` header — the key itself never travels over the wire again.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Data Retention
|
|
130
|
+
|
|
131
|
+
Events are automatically deleted after **90 days**. The Cloudflare Worker runs a daily scheduled cleanup to enforce this.
|
|
132
|
+
|
|
133
|
+
Installations are retained as long as they have events within the 90-day window.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## What the Data Is Used For
|
|
138
|
+
|
|
139
|
+
- Identifying which tools are used most and least
|
|
140
|
+
- Measuring error rates and common failure patterns
|
|
141
|
+
- Tracking performance across platforms
|
|
142
|
+
- Understanding fleet size distribution
|
|
143
|
+
- Guiding feature prioritization
|
|
144
|
+
|
|
145
|
+
The data is never sold, shared with third parties, or used for advertising.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Manage Your Data
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Check status
|
|
153
|
+
nexus telemetry status
|
|
154
|
+
|
|
155
|
+
# View queued events (local only)
|
|
156
|
+
# cat ~/Library/Application\ Support/Local/nexus-ai/telemetry/events.jsonl
|
|
157
|
+
|
|
158
|
+
# Clear local queue
|
|
159
|
+
nexus telemetry clear
|
|
160
|
+
|
|
161
|
+
# Disable permanently
|
|
162
|
+
nexus telemetry disable
|
|
163
|
+
|
|
164
|
+
# Full reset (new installation ID, disables telemetry)
|
|
165
|
+
nexus telemetry reset --confirm
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
To request deletion of server-side data associated with your `installationId`, open a GitHub issue at [github.com/jpollock/local-addon-nexus-ai](https://github.com/jpollock/local-addon-nexus-ai/issues) with the subject "Telemetry data deletion request" and include your `installationId` from `nexus telemetry status`.
|
package/docs-site/mkdocs.yml
CHANGED
package/lib/cli/index.js
CHANGED
|
@@ -54,6 +54,7 @@ const audit_1 = require("./commands/audit");
|
|
|
54
54
|
const bootstrap_1 = require("./bootstrap");
|
|
55
55
|
const version_1 = require("./utils/version");
|
|
56
56
|
const context_1 = require("./utils/context");
|
|
57
|
+
const telemetry_1 = require("./utils/telemetry");
|
|
57
58
|
const program = new commander_1.Command();
|
|
58
59
|
program
|
|
59
60
|
.name('nexus')
|
|
@@ -136,8 +137,23 @@ async function main() {
|
|
|
136
137
|
// Non-blocking — don't fail startup if this check errors
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
|
-
// Parse arguments
|
|
140
|
-
|
|
140
|
+
// Parse arguments — use parseAsync so async command actions are properly awaited
|
|
141
|
+
const commandName = (0, telemetry_1.deriveCommandName)();
|
|
142
|
+
(0, telemetry_1.startTracking)(commandName);
|
|
143
|
+
let parseSuccess = true;
|
|
144
|
+
let parseError;
|
|
145
|
+
try {
|
|
146
|
+
await program.parseAsync();
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
parseSuccess = false;
|
|
150
|
+
parseError = err;
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
await (0, telemetry_1.finishTracking)(parseSuccess);
|
|
154
|
+
}
|
|
155
|
+
if (parseError)
|
|
156
|
+
throw parseError;
|
|
141
157
|
}
|
|
142
158
|
// Run main
|
|
143
159
|
main().catch((error) => {
|
package/lib/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;AACA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,yCAAoC;AACpC,4CAAgD;AAChD,sCAA0C;AAC1C,0CAA8C;AAC9C,wCAA4C;AAC5C,sDAA0D;AAC1D,8CAAkD;AAClD,4CAAgD;AAChD,gDAAoD;AACpD,sCAA0C;AAC1C,4CAAgD;AAChD,2CAAwC;AACxC,6CAAqE;AACrE,6CAAqD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;AACA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,yCAAoC;AACpC,4CAAgD;AAChD,sCAA0C;AAC1C,0CAA8C;AAC9C,wCAA4C;AAC5C,sDAA0D;AAC1D,8CAAkD;AAClD,4CAAgD;AAChD,gDAAoD;AACpD,sCAA0C;AAC1C,4CAAgD;AAChD,2CAAwC;AACxC,6CAAqE;AACrE,6CAAqD;AACrD,iDAAqF;AAErF,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,8DAA8D,CAAC;KAC3E,OAAO,CAAC,IAAA,2BAAiB,GAAE,CAAC,CAAC;AAEhC,eAAe;AACf,OAAO,CAAC,UAAU,CAAC,oBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,cAAS,CAAC,CAAC;AAC9B,OAAO,CAAC,UAAU,CAAC,kBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,gBAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,8BAAiB,CAAC,CAAC;AACtC,OAAO,CAAC,UAAU,CAAC,sBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,oBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,wBAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,cAAS,CAAC,CAAC;AAC9B,OAAO,CAAC,UAAU,CAAC,oBAAY,CAAC,CAAC;AAEjC,uBAAuB;AACvB,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,KAAU,EAAE,EAAE;IAC9C,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACtD,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,mCAAmC;IACnC,IAAA,yBAAe,GAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAElC,kEAAkE;IAClE,mFAAmF;IACnF,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEvD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAEpD,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAS,EAAC;YAC7B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM;YACrC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;gBACnB,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,MAAM,OAAO,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,aAAa;YACnE,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;YACvC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;gBACnD,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;gBAChC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC;YACrE,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,aAAa;QACnE,CAAC;QAED,wDAAwD;QACxD,IAAA,4BAAkB,EAAC,MAAM,CAAC,CAAC;QAE3B,uCAAuC;QACvC,IAAI,CAAC;YACH,MAAM,EAAE,SAAS,EAAE,GAAG,wDAAa,iBAAiB,GAAC,CAAC;YACtD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,MAAM,CAA4B;;OAEnE,EAAE,EAAE,CAAC,CAAC;YACP,IAAI,YAAY,CAAC,gBAAgB,EAAE,OAAO,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;gBAC/F,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,yDAAyD;QAC3D,CAAC;IACH,CAAC;IAED,iFAAiF;IACjF,MAAM,WAAW,GAAG,IAAA,6BAAiB,GAAE,CAAC;IACxC,IAAA,yBAAa,EAAC,WAAW,CAAC,CAAC;IAC3B,IAAI,YAAY,GAAG,IAAI,CAAC;IACxB,IAAI,UAAmB,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,YAAY,GAAG,KAAK,CAAC;QACrB,UAAU,GAAG,GAAG,CAAC;IACnB,CAAC;YAAS,CAAC;QACT,MAAM,IAAA,0BAAc,EAAC,YAAY,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,UAAU;QAAE,MAAM,UAAU,CAAC;AACnC,CAAC;AAED,WAAW;AACX,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACtD,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Telemetry
|
|
3
|
+
*
|
|
4
|
+
* Records anonymous usage data for CLI commands and transmits to the same
|
|
5
|
+
* Cloudflare Worker as the addon's MCP telemetry — unified analytics with
|
|
6
|
+
* access_method: 'cli' to distinguish CLI from MCP invocations.
|
|
7
|
+
*
|
|
8
|
+
* Shares config.json with the addon so both CLI and MCP use the same
|
|
9
|
+
* installationId — correlating usage from the same machine.
|
|
10
|
+
*
|
|
11
|
+
* Pattern: startTracking() before command, finishTracking() after.
|
|
12
|
+
* Both are called from index.ts — no per-command boilerplate needed.
|
|
13
|
+
*/
|
|
14
|
+
/** Call before program.parseAsync() with the derived command name. */
|
|
15
|
+
export declare function startTracking(commandName: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Call after program.parseAsync() — records and transmits the event.
|
|
18
|
+
* Awaiting this ensures the HTTP request completes before process exit.
|
|
19
|
+
*/
|
|
20
|
+
export declare function finishTracking(success: boolean, errorCategory?: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Derive a clean command name from process.argv.
|
|
23
|
+
* ['nexus', 'ai', 'config', '--gateway', 'on'] → 'ai.config'
|
|
24
|
+
* ['nexus', 'sites', 'list'] → 'sites.list'
|
|
25
|
+
*/
|
|
26
|
+
export declare function deriveCommandName(): string;
|
|
27
|
+
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA0HH,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAGvD;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM5F;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CLI Telemetry
|
|
4
|
+
*
|
|
5
|
+
* Records anonymous usage data for CLI commands and transmits to the same
|
|
6
|
+
* Cloudflare Worker as the addon's MCP telemetry — unified analytics with
|
|
7
|
+
* access_method: 'cli' to distinguish CLI from MCP invocations.
|
|
8
|
+
*
|
|
9
|
+
* Shares config.json with the addon so both CLI and MCP use the same
|
|
10
|
+
* installationId — correlating usage from the same machine.
|
|
11
|
+
*
|
|
12
|
+
* Pattern: startTracking() before command, finishTracking() after.
|
|
13
|
+
* Both are called from index.ts — no per-command boilerplate needed.
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.startTracking = startTracking;
|
|
50
|
+
exports.finishTracking = finishTracking;
|
|
51
|
+
exports.deriveCommandName = deriveCommandName;
|
|
52
|
+
const crypto = __importStar(require("crypto"));
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
const path = __importStar(require("path"));
|
|
55
|
+
const os = __importStar(require("os"));
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Shared config location (same as addon main process)
|
|
58
|
+
// ============================================================================
|
|
59
|
+
const CONFIG_DIR = path.join(os.homedir(), 'Library', 'Application Support', 'Local', 'nexus-ai');
|
|
60
|
+
const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json');
|
|
61
|
+
const ENDPOINT = (process.env.NEXUS_ANALYTICS_ENDPOINT?.replace(/\/$/, '') || 'https://nexus-analytics.jeremy7746.workers.dev') + '/v1/events';
|
|
62
|
+
const TIMEOUT_MS = 5000;
|
|
63
|
+
const SESSION_ID = crypto.randomUUID();
|
|
64
|
+
const ADDON_VERSION = require('../../../package.json').version;
|
|
65
|
+
const CI_ENV_VARS = ['CI', 'GITHUB_ACTIONS', 'GITLAB_CI', 'JENKINS_URL', 'TRAVIS', 'CIRCLECI', 'BUILDKITE'];
|
|
66
|
+
function readConfig() {
|
|
67
|
+
try {
|
|
68
|
+
if (fs.existsSync(CONFIG_PATH)) {
|
|
69
|
+
const raw = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf-8'));
|
|
70
|
+
if (raw.installationId && raw.secretKey)
|
|
71
|
+
return raw;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch { /* corrupted — fall through */ }
|
|
75
|
+
return {};
|
|
76
|
+
}
|
|
77
|
+
function isEnabled() {
|
|
78
|
+
if (process.env.NEXUS_TELEMETRY === '0')
|
|
79
|
+
return false;
|
|
80
|
+
if (process.env.NEXUS_TELEMETRY === '1')
|
|
81
|
+
return true;
|
|
82
|
+
if (CI_ENV_VARS.some((v) => process.env[v]))
|
|
83
|
+
return false;
|
|
84
|
+
return readConfig().telemetry?.enabled !== false; // default: enabled
|
|
85
|
+
}
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// HMAC signing (same algorithm as addon and Cloudflare Worker)
|
|
88
|
+
// ============================================================================
|
|
89
|
+
function signData(data, secretKey) {
|
|
90
|
+
const key = Buffer.from(secretKey, 'base64');
|
|
91
|
+
return crypto.createHmac('sha256', key).update(data).digest('hex');
|
|
92
|
+
}
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// Transmission
|
|
95
|
+
// ============================================================================
|
|
96
|
+
async function transmit(commandName, durationMs, success, errorCategory) {
|
|
97
|
+
// Read config once — consistent installationId + secretKey throughout
|
|
98
|
+
const config = readConfig();
|
|
99
|
+
if (!config.installationId || !config.secretKey)
|
|
100
|
+
return; // no config yet — skip
|
|
101
|
+
const event = {
|
|
102
|
+
installation_id: config.installationId,
|
|
103
|
+
session_id: SESSION_ID,
|
|
104
|
+
addon_version: ADDON_VERSION,
|
|
105
|
+
os: process.platform,
|
|
106
|
+
node_version: process.version,
|
|
107
|
+
event_type: 'tool_call',
|
|
108
|
+
timestamp: new Date().toISOString(),
|
|
109
|
+
tool_name: commandName,
|
|
110
|
+
access_method: 'cli',
|
|
111
|
+
success,
|
|
112
|
+
duration_ms: Math.round(durationMs),
|
|
113
|
+
...(errorCategory ? { error_category: errorCategory } : {}),
|
|
114
|
+
};
|
|
115
|
+
const body = JSON.stringify(event);
|
|
116
|
+
const signature = signData(body, config.secretKey);
|
|
117
|
+
const isFirstRequest = !config.registeredAt;
|
|
118
|
+
const headers = {
|
|
119
|
+
'Content-Type': 'application/json',
|
|
120
|
+
'X-Installation-Id': config.installationId,
|
|
121
|
+
'X-Signature': signature,
|
|
122
|
+
};
|
|
123
|
+
if (isFirstRequest) {
|
|
124
|
+
headers['X-Secret-Key'] = config.secretKey;
|
|
125
|
+
}
|
|
126
|
+
const controller = new AbortController();
|
|
127
|
+
const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
128
|
+
try {
|
|
129
|
+
const response = await fetch(ENDPOINT, { method: 'POST', headers, body, signal: controller.signal });
|
|
130
|
+
if (response.ok && isFirstRequest) {
|
|
131
|
+
// Mark registered so we stop sending X-Secret-Key
|
|
132
|
+
try {
|
|
133
|
+
const raw = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf-8'));
|
|
134
|
+
raw.registeredAt = new Date().toISOString();
|
|
135
|
+
const tmp = `${CONFIG_PATH}.${process.pid}.tmp`;
|
|
136
|
+
fs.writeFileSync(tmp, JSON.stringify(raw, null, 2), 'utf-8');
|
|
137
|
+
fs.chmodSync(tmp, 0o600);
|
|
138
|
+
fs.renameSync(tmp, CONFIG_PATH);
|
|
139
|
+
}
|
|
140
|
+
catch { /* best-effort */ }
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch { /* never block CLI */ }
|
|
144
|
+
finally {
|
|
145
|
+
clearTimeout(timeoutId);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// ============================================================================
|
|
149
|
+
// Public API — startTracking / finishTracking
|
|
150
|
+
// ============================================================================
|
|
151
|
+
let _startTime = null;
|
|
152
|
+
let _commandName = null;
|
|
153
|
+
/** Call before program.parseAsync() with the derived command name. */
|
|
154
|
+
function startTracking(commandName) {
|
|
155
|
+
_startTime = Date.now();
|
|
156
|
+
_commandName = commandName;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Call after program.parseAsync() — records and transmits the event.
|
|
160
|
+
* Awaiting this ensures the HTTP request completes before process exit.
|
|
161
|
+
*/
|
|
162
|
+
async function finishTracking(success, errorCategory) {
|
|
163
|
+
if (!isEnabled() || !_startTime || !_commandName)
|
|
164
|
+
return;
|
|
165
|
+
const duration = Date.now() - _startTime;
|
|
166
|
+
await transmit(_commandName, duration, success, errorCategory).catch(() => { });
|
|
167
|
+
_startTime = null;
|
|
168
|
+
_commandName = null;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Derive a clean command name from process.argv.
|
|
172
|
+
* ['nexus', 'ai', 'config', '--gateway', 'on'] → 'ai.config'
|
|
173
|
+
* ['nexus', 'sites', 'list'] → 'sites.list'
|
|
174
|
+
*/
|
|
175
|
+
function deriveCommandName() {
|
|
176
|
+
const args = process.argv.slice(2).filter((a) => !a.startsWith('-'));
|
|
177
|
+
return args.slice(0, 2).join('.') || 'unknown';
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../../src/cli/utils/telemetry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry-config.d.ts","sourceRoot":"","sources":["../../../src/main/telemetry/telemetry-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,CAAC;CACH;AA8BD,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAG7C;AAgBD,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAMD,wBAAgB,UAAU,IAAI,eAAe,
|
|
1
|
+
{"version":3,"file":"telemetry-config.d.ts","sourceRoot":"","sources":["../../../src/main/telemetry/telemetry-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,CAAC;CACH;AA8BD,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAG7C;AAgBD,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAMD,wBAAgB,UAAU,IAAI,eAAe,CA8C5C;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAQzD;AAMD,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAMD,wBAAgB,kBAAkB,IAAI,OAAO,CAU5C;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAK1D;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAMD,eAAO,MAAM,UAAU,QAAQ,CAAC;AAEhC,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAc3C;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,CAO5C;AAED,wBAAgB,UAAU,IAAI,GAAG,EAAE,CAclC;AAED,wBAAgB,WAAW,IAAI,IAAI,CASlC;AAMD,wBAAgB,cAAc,IAAI,IAAI,CAQrC"}
|
|
@@ -159,11 +159,19 @@ function readConfig() {
|
|
|
159
159
|
// Corrupted config, will regenerate
|
|
160
160
|
}
|
|
161
161
|
// Default: enabled (opt-out model) with new credentials
|
|
162
|
-
|
|
162
|
+
// Write to disk immediately so the same IDs are used on every subsequent call
|
|
163
|
+
const fresh = {
|
|
163
164
|
installationId: generateInstallationId(),
|
|
164
165
|
secretKey: generateSecretKey(),
|
|
165
166
|
telemetry: { enabled: true, promptedAt: null },
|
|
166
167
|
};
|
|
168
|
+
try {
|
|
169
|
+
writeConfig(fresh);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// Best-effort — if we can't write, IDs will be inconsistent but telemetry still works
|
|
173
|
+
}
|
|
174
|
+
return fresh;
|
|
167
175
|
}
|
|
168
176
|
function writeConfig(config) {
|
|
169
177
|
ensureDir(CONFIG_DIR);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry-config.js","sourceRoot":"","sources":["../../../src/main/telemetry/telemetry-config.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDH,oCAEC;AAED,sCAEC;AAED,oCAEC;AAED,sCAEC;AAED,oDAGC;AAgBD,wDAEC;AAED,8CAEC;AAMD,
|
|
1
|
+
{"version":3,"file":"telemetry-config.js","sourceRoot":"","sources":["../../../src/main/telemetry/telemetry-config.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/cli/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { auditCommand } from './commands/audit';
|
|
|
20
20
|
import { bootstrap } from './bootstrap';
|
|
21
21
|
import { checkForUpdates, getCurrentVersion } from './utils/version';
|
|
22
22
|
import { setBootstrapResult } from './utils/context';
|
|
23
|
+
import { startTracking, finishTracking, deriveCommandName } from './utils/telemetry';
|
|
23
24
|
|
|
24
25
|
const program = new Command();
|
|
25
26
|
|
|
@@ -115,8 +116,20 @@ async function main() {
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
// Parse arguments
|
|
119
|
-
|
|
119
|
+
// Parse arguments — use parseAsync so async command actions are properly awaited
|
|
120
|
+
const commandName = deriveCommandName();
|
|
121
|
+
startTracking(commandName);
|
|
122
|
+
let parseSuccess = true;
|
|
123
|
+
let parseError: unknown;
|
|
124
|
+
try {
|
|
125
|
+
await program.parseAsync();
|
|
126
|
+
} catch (err) {
|
|
127
|
+
parseSuccess = false;
|
|
128
|
+
parseError = err;
|
|
129
|
+
} finally {
|
|
130
|
+
await finishTracking(parseSuccess);
|
|
131
|
+
}
|
|
132
|
+
if (parseError) throw parseError;
|
|
120
133
|
}
|
|
121
134
|
|
|
122
135
|
// Run main
|