eklavya 1.29.0 → 1.30.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.
@@ -0,0 +1,278 @@
1
+ /**
2
+ * The ping itself: what `eklavya telemetry show` prints and `send` posts.
3
+ * Split from `telemetry.ts` so hooks never load these imports. Every field is
4
+ * listed on `/docs/usage-analytics/`; change the two together.
5
+ */
6
+ import fs from 'node:fs';
7
+ import path from 'node:path';
8
+ import { dbPath, projectsDir } from './paths.js';
9
+ import { loadGlobalConfig } from './config.js';
10
+ import { runtimeVersion, readState as readUpdateState } from './update.js';
11
+ import { listArtifacts } from './artifacts.js';
12
+ import { MASTERY_THRESHOLD, MIN_REPS_FOR_KNOWN } from './srs.js';
13
+ import { PASSING_GRADE } from './store.js';
14
+ import { API_SECRET, MEASUREMENT_ID, canSend, disabledReason, installId, readState, today, writeState, } from './telemetry.js';
15
+ const ENDPOINT = 'https://www.google-analytics.com/mp/collect';
16
+ /** The observer's own `claude -p` sessions, recognised as `HELPER_SESSION` does. Not the developer's work. */
17
+ const HELPERS = `(SELECT session_id FROM evidence_events WHERE kind = 'prompt' AND body LIKE '<evidence project=%')`;
18
+ const NOT_HELPER = `(session_id IS NULL OR session_id NOT IN ${HELPERS})`;
19
+ const DAY_MS = 86_400_000;
20
+ const num = (db, sql, ...args) => {
21
+ try {
22
+ const row = db.prepare(sql).get(...args);
23
+ const v = row ? Object.values(row)[0] : 0;
24
+ return typeof v === 'number' ? v : Number(v) || 0;
25
+ }
26
+ catch {
27
+ return 0;
28
+ }
29
+ };
30
+ /**
31
+ * SQLite's own timestamp format. Columns are compared through `datetime(col)`
32
+ * because some are written by `datetime('now')` and some by `nowIso()`: raw,
33
+ * `2026-09-24T03:00Z` sorts after `2026-09-24 05:00` and a row counted in the
34
+ * last ping would be counted again.
35
+ */
36
+ const sqlTime = (ms) => new Date(ms).toISOString().slice(0, 19).replace('T', ' ');
37
+ function projectSettings() {
38
+ let total = 0, quizOff = 0, memoryOff = 0, overrides = 0;
39
+ try {
40
+ for (const d of fs.readdirSync(projectsDir(), { withFileTypes: true })) {
41
+ if (!d.isDirectory())
42
+ continue;
43
+ let raw;
44
+ try {
45
+ raw = JSON.parse(fs.readFileSync(path.join(projectsDir(), d.name, 'config.json'), 'utf8'));
46
+ }
47
+ catch {
48
+ continue;
49
+ }
50
+ total++;
51
+ if (Object.keys(raw).length > 0)
52
+ overrides++;
53
+ if (raw.quiz?.enabled === false || raw.mode === 'off')
54
+ quizOff++;
55
+ if (raw.memory?.enabled === false)
56
+ memoryOff++;
57
+ }
58
+ }
59
+ catch {
60
+ /* no projects folder yet */
61
+ }
62
+ return { project_configs: total, projects_quiz_off: quizOff, projects_memory_off: memoryOff, projects_with_settings: overrides };
63
+ }
64
+ function artifactCounts(since) {
65
+ const out = { artifacts_total: 0, artifacts_new: 0, explainers_total: 0, explainers_new: 0 };
66
+ try {
67
+ for (const a of listArtifacts()) {
68
+ const fresh = Date.parse(a.created) >= since;
69
+ if (a.kind === 'explainer') {
70
+ out.explainers_total++;
71
+ if (fresh)
72
+ out.explainers_new++;
73
+ }
74
+ else {
75
+ out.artifacts_total++;
76
+ if (fresh)
77
+ out.artifacts_new++;
78
+ }
79
+ }
80
+ }
81
+ catch {
82
+ /* no artifacts yet */
83
+ }
84
+ return out;
85
+ }
86
+ /**
87
+ * Every event of one ping. `since` is the last accepted ping (or a day ago),
88
+ * so the `_new` counts add up across days without double counting; `_total`
89
+ * and snapshot values are the state now.
90
+ */
91
+ export function buildEvents(db, now = Date.now(), state = readState()) {
92
+ const sent = state.sent_at ? Date.parse(state.sent_at) : NaN;
93
+ const since = Number.isFinite(sent) ? sent : now - DAY_MS;
94
+ const t = sqlTime(since);
95
+ const known = `score >= ${MASTERY_THRESHOLD} AND reps >= ${MIN_REPS_FOR_KNOWN}`;
96
+ const c = loadGlobalConfig();
97
+ const days = new Set(state.active_days ?? []);
98
+ const lastWeek = Array.from({ length: 7 }, (_, i) => today(now - i * DAY_MS)).filter((d) => days.has(d)).length;
99
+ const u = readUpdateState();
100
+ const created = state.created_at ? Date.parse(state.created_at) : now;
101
+ const active = {
102
+ name: 'daily_active',
103
+ params: {
104
+ version: runtimeVersion() ?? 'unknown',
105
+ os: process.platform,
106
+ node_major: Number(process.versions.node.split('.')[0]),
107
+ install_age_days: Math.max(0, Math.floor((now - created) / DAY_MS)),
108
+ active_days_7d: lastWeek,
109
+ sessions_new: num(db, `SELECT COUNT(*) FROM (SELECT session_id FROM evidence_events WHERE datetime(received_at) >= ?
110
+ UNION SELECT session_id FROM gates WHERE datetime(updated_at) >= ?) WHERE session_id NOT IN ${HELPERS}`, t, t),
111
+ // Should be 0. Non-zero means the observer's own sessions are being
112
+ // recorded as work again (the 1.24.0 incident; see HELPER_SESSION).
113
+ helper_sessions_new: num(db, `SELECT COUNT(DISTINCT session_id) FROM evidence_events WHERE datetime(received_at) >= ? AND session_id IN ${HELPERS}`, t),
114
+ update_error: u.error_class ?? (u.error ? 'other' : 'none'),
115
+ },
116
+ };
117
+ const settings = {
118
+ name: 'settings',
119
+ params: {
120
+ quiz_enabled: c.quiz.enabled,
121
+ quiz_enforced: c.quiz.enforced,
122
+ focus: c.focus,
123
+ cadence: c.cadence,
124
+ difficulty: c.difficulty,
125
+ explain_on_wrong: c.explain_on_wrong,
126
+ quiet: c.quiet,
127
+ auto_update: c.auto_update,
128
+ memory_enabled: c.memory.enabled,
129
+ memory_capture: c.memory.capture,
130
+ retention_set: c.memory.retention_days !== null,
131
+ retrieval_mode: c.retrieval.mode,
132
+ cross_project: c.retrieval.cross_project,
133
+ observer: c.providers.observer?.kind ?? 'none',
134
+ embeddings: c.providers.embeddings?.kind ?? 'none',
135
+ notifications: c.notifications.enabled,
136
+ sync: c.sync.enabled,
137
+ privacy_rules: c.privacy.exclude_paths.length + c.privacy.exclude_tools.length + c.privacy.redact_patterns.length,
138
+ ...projectSettings(),
139
+ projects_known: num(db, `SELECT COUNT(*) FROM (SELECT repo AS p FROM gates WHERE repo IS NOT NULL AND repo <> '*'
140
+ UNION SELECT project FROM evidence_events WHERE project <> '*')`),
141
+ },
142
+ };
143
+ const learning = {
144
+ name: 'learning',
145
+ params: {
146
+ questions_new: num(db, 'SELECT COUNT(*) FROM attempts WHERE datetime(ts) >= ?', t),
147
+ answered_new: num(db, "SELECT COUNT(*) FROM attempts WHERE datetime(ts) >= ? AND COALESCE(outcome, 'answered') = 'answered'", t),
148
+ passed_new: num(db, "SELECT COUNT(*) FROM attempts WHERE datetime(ts) >= ? AND COALESCE(outcome, 'answered') = 'answered' AND grade >= ?", t, PASSING_GRADE),
149
+ dont_know_new: num(db, "SELECT COUNT(*) FROM attempts WHERE datetime(ts) >= ? AND outcome = 'dont_know'", t),
150
+ declined_new: num(db, "SELECT COUNT(*) FROM attempts WHERE datetime(ts) >= ? AND outcome = 'declined'", t),
151
+ mcq_new: num(db, "SELECT COUNT(*) FROM attempts WHERE datetime(ts) >= ? AND format = 'mcq'", t),
152
+ questions_total: num(db, 'SELECT COUNT(*) FROM attempts'),
153
+ concepts_logged_new: num(db, 'SELECT COUNT(DISTINCT concept_id) FROM session_concepts WHERE datetime(ts) >= ?', t),
154
+ concepts_mastered: num(db, `SELECT COUNT(*) FROM mastery WHERE ${known}`),
155
+ concepts_learning: num(db, `SELECT COUNT(*) FROM mastery WHERE reps > 0 AND NOT (${known})`),
156
+ concepts_backlog: num(db, `SELECT COUNT(DISTINCT concept_id) FROM session_concepts
157
+ WHERE COALESCE(origin, 'work') = 'work' AND concept_id NOT IN (SELECT concept_id FROM attempts)`),
158
+ reviews_due: num(db, 'SELECT COUNT(*) FROM mastery WHERE reps > 0 AND next_review IS NOT NULL AND next_review <= ?', new Date(now).toISOString()),
159
+ level_easy: num(db, "SELECT COUNT(*) FROM project_levels WHERE level = 'easy'"),
160
+ level_medium: num(db, "SELECT COUNT(*) FROM project_levels WHERE level = 'medium'"),
161
+ level_hard: num(db, "SELECT COUNT(*) FROM project_levels WHERE level = 'hard'"),
162
+ promotions_new: num(db, 'SELECT COUNT(*) FROM project_levels WHERE datetime(promoted_at) >= ?', t),
163
+ gates_enforced_new: num(db, "SELECT COUNT(*) FROM gates WHERE mode = 'enforced' AND datetime(updated_at) >= ?", t),
164
+ gates_passed_new: num(db, "SELECT COUNT(*) FROM gates WHERE mode = 'enforced' AND passed = 1 AND datetime(updated_at) >= ?", t),
165
+ },
166
+ };
167
+ const memory = {
168
+ name: 'memory',
169
+ params: {
170
+ events_new: num(db, `SELECT COUNT(*) FROM evidence_events WHERE datetime(received_at) >= ? AND session_id NOT IN ${HELPERS}`, t),
171
+ entries_new: num(db, 'SELECT COUNT(*) FROM memory_entries WHERE deleted_at IS NULL AND datetime(created_at) >= ?', t),
172
+ corrected_new: num(db, 'SELECT COUNT(*) FROM memory_entries WHERE superseded_by IS NOT NULL AND datetime(created_at) >= ?', t),
173
+ deleted_new: num(db, 'SELECT COUNT(*) FROM memory_entries WHERE datetime(deleted_at) >= ?', t),
174
+ entries_total: num(db, 'SELECT COUNT(*) FROM memory_entries WHERE deleted_at IS NULL AND superseded_by IS NULL'),
175
+ recalls_new: num(db, `SELECT COUNT(*) FROM context_receipts WHERE datetime(created_at) >= ? AND ${NOT_HELPER}`, t),
176
+ recalls_session_start_new: num(db, `SELECT COUNT(*) FROM context_receipts WHERE scope = 'session_start' AND datetime(created_at) >= ? AND ${NOT_HELPER}`, t),
177
+ recalls_search_new: num(db, `SELECT COUNT(*) FROM context_receipts WHERE scope = 'search' AND datetime(created_at) >= ? AND ${NOT_HELPER}`, t),
178
+ recall_items_new: num(db, `SELECT COALESCE(SUM(item_count), 0) FROM context_receipts WHERE datetime(created_at) >= ? AND ${NOT_HELPER}`, t),
179
+ recall_tokens_new: num(db, `SELECT COALESCE(SUM(delivered_tokens), 0) FROM context_receipts WHERE datetime(created_at) >= ? AND ${NOT_HELPER}`, t),
180
+ recall_tokens_saved_new: num(db, `SELECT COALESCE(SUM(MAX(base_tokens - delivered_tokens, 0)), 0) FROM context_receipts WHERE datetime(created_at) >= ? AND ${NOT_HELPER}`, t),
181
+ jobs_pending: num(db, "SELECT COUNT(*) FROM memory_jobs WHERE status IN ('pending','claimed','paused')"),
182
+ jobs_failed: num(db, "SELECT COUNT(*) FROM memory_jobs WHERE status = 'failed'"),
183
+ collections: num(db, 'SELECT COUNT(*) FROM memory_collections'),
184
+ db_mb: (() => {
185
+ try {
186
+ return Math.round(fs.statSync(dbPath()).size / 1_048_576);
187
+ }
188
+ catch {
189
+ return 0;
190
+ }
191
+ })(),
192
+ },
193
+ };
194
+ const artifacts = { name: 'artifacts', params: artifactCounts(since) };
195
+ // Finished days only: today's counts are still growing and go out tomorrow.
196
+ const uses = [];
197
+ try {
198
+ const rows = db
199
+ .prepare('SELECT name, SUM(n) AS n FROM usage_counts WHERE day < ? GROUP BY name ORDER BY name')
200
+ .all(today(now));
201
+ for (const r of rows) {
202
+ const [kind, ...rest] = r.name.split(':');
203
+ uses.push({ name: 'feature_use', params: { kind: kind, feature: rest.join(':') || kind, count: r.n } });
204
+ }
205
+ }
206
+ catch {
207
+ /* an older schema */
208
+ }
209
+ return [active, settings, learning, memory, artifacts, ...uses];
210
+ }
211
+ /**
212
+ * The guarantee the docs make, enforced: a string is only ever an enum-like
213
+ * token, never free text. Throws, so a regression fails a test or skips a ping
214
+ * instead of sending something it should not.
215
+ */
216
+ export function assertSafe(events) {
217
+ for (const e of events) {
218
+ if (!/^[a-z_]{1,40}$/.test(e.name))
219
+ throw new Error(`telemetry: bad event name ${e.name}`);
220
+ const keys = Object.keys(e.params);
221
+ // GA4 allows 25, and `post` adds `engagement_time_msec` to every event.
222
+ if (keys.length > 24)
223
+ throw new Error(`telemetry: ${e.name} has ${keys.length} params`);
224
+ for (const [k, v] of Object.entries(e.params)) {
225
+ if (!/^[a-z0-9_]{1,40}$/.test(k))
226
+ throw new Error(`telemetry: bad param ${k}`);
227
+ if (typeof v === 'number' && Number.isFinite(v))
228
+ continue;
229
+ if (typeof v === 'boolean')
230
+ continue;
231
+ if (typeof v === 'string' && /^[a-z0-9_.:-]{1,40}$/i.test(v))
232
+ continue;
233
+ throw new Error(`telemetry: ${e.name}.${k} is not a count, flag or token`);
234
+ }
235
+ }
236
+ }
237
+ /** POSTs events in GA4's batches of 25. True when every batch was accepted. */
238
+ export async function post(events, id = installId()) {
239
+ if (!MEASUREMENT_ID || !API_SECRET)
240
+ return false;
241
+ assertSafe(events);
242
+ const url = `${ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`;
243
+ for (let i = 0; i < events.length; i += 25) {
244
+ const body = {
245
+ client_id: id,
246
+ // Without engagement time GA4 does not count the install as an active user.
247
+ events: events.slice(i, i + 25).map((e) => ({ name: e.name, params: { ...e.params, engagement_time_msec: 1 } })),
248
+ };
249
+ const res = await fetch(url, { method: 'POST', body: JSON.stringify(body), signal: AbortSignal.timeout(5000) });
250
+ if (!res.ok)
251
+ return false;
252
+ }
253
+ return true;
254
+ }
255
+ /** `eklavya telemetry send`: build, post, and on success move the window and clear sent counters. */
256
+ export async function sendNow(db, now = Date.now()) {
257
+ if (disabledReason() || !canSend())
258
+ return false;
259
+ const events = buildEvents(db, now);
260
+ const ok = await post(events).catch(() => false);
261
+ if (ok) {
262
+ writeState({ sent_at: new Date(now).toISOString() });
263
+ try {
264
+ db.prepare('DELETE FROM usage_counts WHERE day < ?').run(today(now));
265
+ }
266
+ catch {
267
+ /* sent twice next time is the worst case */
268
+ }
269
+ }
270
+ return ok;
271
+ }
272
+ /** A single event, sent in the open — `uninstall` uses it before the runtime goes. */
273
+ export async function sendOne(name, params = {}) {
274
+ if (disabledReason() || !canSend())
275
+ return;
276
+ await post([{ name, params: { version: runtimeVersion() ?? 'unknown', os: process.platform, ...params } }]).catch(() => false);
277
+ }
278
+ //# sourceMappingURL=telemetry-send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry-send.js","sourceRoot":"","sources":["../src/telemetry-send.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EACL,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,GAE7F,MAAM,gBAAgB,CAAC;AAGxB,MAAM,QAAQ,GAAG,6CAA6C,CAAC;AAC/D,8GAA8G;AAC9G,MAAM,OAAO,GAAG,oGAAoG,CAAC;AACrH,MAAM,UAAU,GAAG,4CAA4C,OAAO,GAAG,CAAC;AAC1E,MAAM,MAAM,GAAG,UAAU,CAAC;AAQ1B,MAAM,GAAG,GAAG,CAAC,EAAM,EAAE,GAAW,EAAE,GAAG,IAAe,EAAU,EAAE;IAC9D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAwC,CAAC;QAChF,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,OAAO,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAE1F,SAAS,eAAe;IACtB,IAAI,KAAK,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;gBAAE,SAAS;YAC/B,IAAI,GAAwB,CAAC;YAC7B,IAAI,CAAC;gBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YAC7F,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,KAAK,EAAE,CAAC;YACR,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS,EAAE,CAAC;YAC7C,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;gBAAE,OAAO,EAAE,CAAC;YACjE,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,KAAK;gBAAE,SAAS,EAAE,CAAC;QACjD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;IAC9B,CAAC;IACD,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,sBAAsB,EAAE,SAAS,EAAE,CAAC;AACnI,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,MAAM,GAAG,GAAG,EAAE,eAAe,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;IAC7F,IAAI,CAAC;QACH,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;YAC7C,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;gBAAC,IAAI,KAAK;oBAAE,GAAG,CAAC,cAAc,EAAE,CAAC;YAAC,CAAC;iBACnF,CAAC;gBAAC,GAAG,CAAC,eAAe,EAAE,CAAC;gBAAC,IAAI,KAAK;oBAAE,GAAG,CAAC,aAAa,EAAE,CAAC;YAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,EAAM,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,QAAwB,SAAS,EAAE;IACvF,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC;IAC1D,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACzB,MAAM,KAAK,GAAG,YAAY,iBAAiB,gBAAgB,kBAAkB,EAAE,CAAC;IAChF,MAAM,CAAC,GAAG,gBAAgB,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAChH,MAAM,CAAC,GAAG,eAAe,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAEtE,MAAM,MAAM,GAAmB;QAC7B,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE;YACN,OAAO,EAAE,cAAc,EAAE,IAAI,SAAS;YACtC,EAAE,EAAE,OAAO,CAAC,QAAQ;YACpB,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACvD,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;YACnE,cAAc,EAAE,QAAQ;YACxB,YAAY,EAAE,GAAG,CACf,EAAE,EACF;wGACgG,OAAO,EAAE,EACzG,CAAC,EAAE,CAAC,CACL;YACD,oEAAoE;YACpE,oEAAoE;YACpE,mBAAmB,EAAE,GAAG,CAAC,EAAE,EAAE,6GAA6G,OAAO,EAAE,EAAE,CAAC,CAAC;YACvJ,YAAY,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;SAC5D;KACF,CAAC;IAEF,MAAM,QAAQ,GAAmB;QAC/B,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE;YACN,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO;YAC5B,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ;YAC9B,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;YACpC,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO;YAChC,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO;YAChC,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,KAAK,IAAI;YAC/C,cAAc,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI;YAChC,aAAa,EAAE,CAAC,CAAC,SAAS,CAAC,aAAa;YACxC,QAAQ,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,IAAI,MAAM;YAC9C,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,IAAI,MAAM;YAClD,aAAa,EAAE,CAAC,CAAC,aAAa,CAAC,OAAO;YACtC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO;YACpB,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,MAAM;YACjH,GAAG,eAAe,EAAE;YACpB,cAAc,EAAE,GAAG,CACjB,EAAE,EACF;0EACkE,CACnE;SACF;KACF,CAAC;IAEF,MAAM,QAAQ,GAAmB;QAC/B,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE;YACN,aAAa,EAAE,GAAG,CAAC,EAAE,EAAE,uDAAuD,EAAE,CAAC,CAAC;YAClF,YAAY,EAAE,GAAG,CAAC,EAAE,EAAE,sGAAsG,EAAE,CAAC,CAAC;YAChI,UAAU,EAAE,GAAG,CAAC,EAAE,EAAE,qHAAqH,EAAE,CAAC,EAAE,aAAa,CAAC;YAC5J,aAAa,EAAE,GAAG,CAAC,EAAE,EAAE,iFAAiF,EAAE,CAAC,CAAC;YAC5G,YAAY,EAAE,GAAG,CAAC,EAAE,EAAE,gFAAgF,EAAE,CAAC,CAAC;YAC1G,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,0EAA0E,EAAE,CAAC,CAAC;YAC/F,eAAe,EAAE,GAAG,CAAC,EAAE,EAAE,+BAA+B,CAAC;YACzD,mBAAmB,EAAE,GAAG,CAAC,EAAE,EAAE,iFAAiF,EAAE,CAAC,CAAC;YAClH,iBAAiB,EAAE,GAAG,CAAC,EAAE,EAAE,sCAAsC,KAAK,EAAE,CAAC;YACzE,iBAAiB,EAAE,GAAG,CAAC,EAAE,EAAE,wDAAwD,KAAK,GAAG,CAAC;YAC5F,gBAAgB,EAAE,GAAG,CACnB,EAAE,EACF;0GACkG,CACnG;YACD,WAAW,EAAE,GAAG,CAAC,EAAE,EAAE,8FAA8F,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;YACjJ,UAAU,EAAE,GAAG,CAAC,EAAE,EAAE,0DAA0D,CAAC;YAC/E,YAAY,EAAE,GAAG,CAAC,EAAE,EAAE,4DAA4D,CAAC;YACnF,UAAU,EAAE,GAAG,CAAC,EAAE,EAAE,0DAA0D,CAAC;YAC/E,cAAc,EAAE,GAAG,CAAC,EAAE,EAAE,sEAAsE,EAAE,CAAC,CAAC;YAClG,kBAAkB,EAAE,GAAG,CAAC,EAAE,EAAE,kFAAkF,EAAE,CAAC,CAAC;YAClH,gBAAgB,EAAE,GAAG,CAAC,EAAE,EAAE,iGAAiG,EAAE,CAAC,CAAC;SAChI;KACF,CAAC;IAEF,MAAM,MAAM,GAAmB;QAC7B,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE;YACN,UAAU,EAAE,GAAG,CAAC,EAAE,EAAE,+FAA+F,OAAO,EAAE,EAAE,CAAC,CAAC;YAChI,WAAW,EAAE,GAAG,CAAC,EAAE,EAAE,4FAA4F,EAAE,CAAC,CAAC;YACrH,aAAa,EAAE,GAAG,CAAC,EAAE,EAAE,mGAAmG,EAAE,CAAC,CAAC;YAC9H,WAAW,EAAE,GAAG,CAAC,EAAE,EAAE,qEAAqE,EAAE,CAAC,CAAC;YAC9F,aAAa,EAAE,GAAG,CAAC,EAAE,EAAE,wFAAwF,CAAC;YAChH,WAAW,EAAE,GAAG,CAAC,EAAE,EAAE,6EAA6E,UAAU,EAAE,EAAE,CAAC,CAAC;YAClH,yBAAyB,EAAE,GAAG,CAAC,EAAE,EAAE,yGAAyG,UAAU,EAAE,EAAE,CAAC,CAAC;YAC5J,kBAAkB,EAAE,GAAG,CAAC,EAAE,EAAE,kGAAkG,UAAU,EAAE,EAAE,CAAC,CAAC;YAC9I,gBAAgB,EAAE,GAAG,CAAC,EAAE,EAAE,iGAAiG,UAAU,EAAE,EAAE,CAAC,CAAC;YAC3I,iBAAiB,EAAE,GAAG,CAAC,EAAE,EAAE,uGAAuG,UAAU,EAAE,EAAE,CAAC,CAAC;YAClJ,uBAAuB,EAAE,GAAG,CAC1B,EAAE,EACF,6HAA6H,UAAU,EAAE,EACzI,CAAC,CACF;YACD,YAAY,EAAE,GAAG,CAAC,EAAE,EAAE,iFAAiF,CAAC;YACxG,WAAW,EAAE,GAAG,CAAC,EAAE,EAAE,0DAA0D,CAAC;YAChF,WAAW,EAAE,GAAG,CAAC,EAAE,EAAE,yCAAyC,CAAC;YAC/D,KAAK,EAAE,CAAC,GAAG,EAAE;gBACX,IAAI,CAAC;oBACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC;gBAC5D,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,CAAC,CAAC;gBACX,CAAC;YACH,CAAC,CAAC,EAAE;SACL;KACF,CAAC;IAEF,MAAM,SAAS,GAAmB,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;IAEvF,4EAA4E;IAC5E,MAAM,IAAI,GAAqB,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE;aACZ,OAAO,CAAC,sFAAsF,CAAC;aAC/F,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAkC,CAAC;QACpD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAK,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qBAAqB;IACvB,CAAC;IAED,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,CAAC;AAClE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,MAAwB;IACjD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3F,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACnC,wEAAwE;QACxE,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,IAAI,QAAQ,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC;QACxF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC;YAC/E,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,SAAS;YAC1D,IAAI,OAAO,CAAC,KAAK,SAAS;gBAAE,SAAS;YACrC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC;gBAAE,SAAS;YACvE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,IAAI,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,MAAwB,EAAE,EAAE,GAAG,SAAS,EAAE;IACnE,IAAI,CAAC,cAAc,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IACjD,UAAU,CAAC,MAAM,CAAC,CAAC;IACnB,MAAM,GAAG,GAAG,GAAG,QAAQ,mBAAmB,cAAc,eAAe,UAAU,EAAE,CAAC;IACpF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG;YACX,SAAS,EAAE,EAAE;YACb,4EAA4E;YAC5E,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;SACjH,CAAC;QACF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,qGAAqG;AACrG,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,EAAM,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IACpD,IAAI,cAAc,EAAE,IAAI,CAAC,OAAO,EAAE;QAAE,OAAO,KAAK,CAAC;IACjD,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,EAAE,EAAE,CAAC;QACP,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,EAAE,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACvE,CAAC;QAAC,MAAM,CAAC;YACP,4CAA4C;QAC9C,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAY,EAAE,SAAgC,EAAE;IAC5E,IAAI,cAAc,EAAE,IAAI,CAAC,OAAO,EAAE;QAAE,OAAO;IAC3C,MAAM,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;AACjI,CAAC"}
@@ -0,0 +1,188 @@
1
+ /**
2
+ * The anonymous usage ping: once a day, a handful of counts and setting values
3
+ * go to Google Analytics 4 over its Measurement Protocol, so the maintainer can
4
+ * see whether Eklavya is installed, kept and useful. `/docs/usage-analytics/`
5
+ * lists every field; `eklavya telemetry show` prints the next ping verbatim.
6
+ *
7
+ * What makes it anonymous is what it is built from, not a promise about it:
8
+ * - every value is a number, a boolean or one of Eklavya's own enum values
9
+ * (`focus: concept`), checked by `assertSafe` before anything is sent;
10
+ * - the only identity is `install_id`, a random UUID made on first use and
11
+ * kept in `telemetry.json` beside the database — per install, not per
12
+ * person, and never in `config.json`, which dotfile managers copy;
13
+ * - nothing is read from a path, a project name, a concept slug, a question,
14
+ * an answer or a memory entry, except to count rows.
15
+ *
16
+ * Off: `telemetry: false` in the global config, `EKLAVYA_TELEMETRY=0`, or
17
+ * `DO_NOT_TRACK=1`. It also never runs outside an installed runtime (a
18
+ * checkout, a test) or under CI.
19
+ *
20
+ * This file is what hooks load, so it stays light; the payload and the
21
+ * network are `telemetry-send.ts`, loaded only by `eklavya telemetry`.
22
+ *
23
+ * Shaped like `update.ts`: the SessionStart hook calls
24
+ * `startBackgroundTelemetry`, which records today as active and, when a ping is
25
+ * due, starts `eklavya telemetry send --background` detached. The hook never
26
+ * waits and every failure is swallowed.
27
+ */
28
+ import fs from 'node:fs';
29
+ import path from 'node:path';
30
+ import { randomUUID } from 'node:crypto';
31
+ import { spawn } from 'node:child_process';
32
+ import Database from 'better-sqlite3';
33
+ import { dbPath, eklavyaHome } from './paths.js';
34
+ import { loadGlobalConfig } from './config.js';
35
+ import { runtimeCli, runtimeVersion } from './update.js';
36
+ /**
37
+ * GA4 property "Eklavya CLI". Not a secret in any useful sense: it ships in
38
+ * the package, so anyone could post events with it. That makes the counts
39
+ * approximate, which is all they are used for. Empty either one to stop sending.
40
+ */
41
+ export const MEASUREMENT_ID = 'G-8XP3NZLJXS';
42
+ export const API_SECRET = 'c2IKL021RiGv3hS0WtOFtw';
43
+ const ACTIVE_DAYS_KEPT = 30;
44
+ /** How long a started send holds its claim: long enough to finish, short enough that a dead one is retried. */
45
+ const ATTEMPT_CLAIM_MS = 3_600_000;
46
+ export function statePath() {
47
+ return path.join(eklavyaHome(), 'telemetry.json');
48
+ }
49
+ export function readState() {
50
+ try {
51
+ const v = JSON.parse(fs.readFileSync(statePath(), 'utf8'));
52
+ return v && typeof v === 'object' ? v : {};
53
+ }
54
+ catch {
55
+ return {};
56
+ }
57
+ }
58
+ export function writeState(patch) {
59
+ try {
60
+ fs.mkdirSync(eklavyaHome(), { recursive: true });
61
+ const tmp = `${statePath()}.${process.pid}.tmp`;
62
+ fs.writeFileSync(tmp, `${JSON.stringify({ ...readState(), ...patch }, null, 2)}\n`, { mode: 0o600 });
63
+ fs.renameSync(tmp, statePath());
64
+ }
65
+ catch {
66
+ /* a lost write costs one duplicate or one missed ping */
67
+ }
68
+ }
69
+ export const today = (now = Date.now()) => new Date(now).toISOString().slice(0, 10);
70
+ const falsy = (v) => v !== undefined && /^(0|false|off|no)$/i.test(v.trim());
71
+ const truthy = (v) => v !== undefined && v.trim() !== '' && !falsy(v);
72
+ /** Why the ping is off, or null when it is on. One place, so `doctor` and `status` agree with `send`. */
73
+ export function disabledReason() {
74
+ if (falsy(process.env.EKLAVYA_TELEMETRY))
75
+ return 'EKLAVYA_TELEMETRY is set';
76
+ if (truthy(process.env.DO_NOT_TRACK))
77
+ return 'DO_NOT_TRACK is set';
78
+ try {
79
+ if (!loadGlobalConfig().telemetry)
80
+ return 'telemetry is false';
81
+ }
82
+ catch {
83
+ /* an unreadable config keeps the default */
84
+ }
85
+ return null;
86
+ }
87
+ /** Can this process send at all? Off in CI, in a checkout or test, and until the property exists. */
88
+ export function canSend() {
89
+ return !process.env.CI && !process.env.EKLAVYA_RUNTIME && !!runtimeVersion() && !!MEASUREMENT_ID && !!API_SECRET;
90
+ }
91
+ export function installId() {
92
+ const s = readState();
93
+ if (s.install_id)
94
+ return s.install_id;
95
+ const id = randomUUID();
96
+ writeState({ install_id: id, created_at: new Date().toISOString() });
97
+ return id;
98
+ }
99
+ /** Called by SessionStart: record the day, and start a send if one is due. Never throws. */
100
+ export function startBackgroundTelemetry(now = Date.now()) {
101
+ try {
102
+ if (disabledReason())
103
+ return;
104
+ const s = readState();
105
+ const day = today(now);
106
+ const days = s.active_days ?? [];
107
+ if (days[days.length - 1] !== day)
108
+ writeState({ active_days: [...days, day].slice(-ACTIVE_DAYS_KEPT) });
109
+ if (!canSend() || !s.announced_at || (s.sent_at && today(Date.parse(s.sent_at)) === day))
110
+ return;
111
+ // Claim before spawning, as `run.mjs` does for its heal: without it two
112
+ // sessions starting together both post the same counts, and offline every
113
+ // session start spawns a send that fails.
114
+ // ponytail: read-then-write, so two starts in the same millisecond can both
115
+ // claim; an exclusive lock file if duplicates ever show up in the counts.
116
+ const tried = s.attempt_at ? Date.parse(s.attempt_at) : NaN;
117
+ if (now - tried < ATTEMPT_CLAIM_MS)
118
+ return;
119
+ writeState({ attempt_at: new Date(now).toISOString() });
120
+ const child = spawn(process.execPath, [runtimeCli(), 'telemetry', 'send', '--background'], {
121
+ detached: true,
122
+ stdio: 'ignore',
123
+ windowsHide: true,
124
+ });
125
+ child.on('error', () => { });
126
+ child.unref();
127
+ }
128
+ catch {
129
+ /* retried next session */
130
+ }
131
+ }
132
+ /**
133
+ * The one line SessionStart shows, once, before the first ping: earlier installs
134
+ * were told "no telemetry", and an update must not change that silently. Null when off or already said.
135
+ */
136
+ export function telemetryNotice() {
137
+ try {
138
+ // Only where a ping can go out: a checkout or CI has nothing to announce.
139
+ if (disabledReason() || !canSend() || readState().announced_at)
140
+ return null;
141
+ return 'Eklavya now sends anonymous daily usage counts, never code, paths or text · turn off: eklavya telemetry off';
142
+ }
143
+ catch {
144
+ return null;
145
+ }
146
+ }
147
+ export function markTelemetryAnnounced(now = Date.now()) {
148
+ writeState({ announced_at: new Date(now).toISOString() });
149
+ }
150
+ /**
151
+ * One more use of a named feature today. Names are Eklavya's own identifiers
152
+ * only — callers pass constants, never input. Never throws: a counter must not
153
+ * cost the command it counts.
154
+ */
155
+ export function countUse(db, name) {
156
+ try {
157
+ if (disabledReason())
158
+ return;
159
+ db.prepare(`INSERT INTO usage_counts (day, name, n) VALUES (?, ?, 1)
160
+ ON CONFLICT(day, name) DO UPDATE SET n = n + 1`).run(today(), name);
161
+ }
162
+ catch {
163
+ /* an older schema, a busy database: skip the count */
164
+ }
165
+ }
166
+ /**
167
+ * `countUse` for the CLI, which mostly has no database open: the file as it
168
+ * is, no migrations, no seed. A command must not pay for opening the full
169
+ * store just to be counted.
170
+ */
171
+ export function countCommand(name) {
172
+ if (disabledReason())
173
+ return;
174
+ let db;
175
+ try {
176
+ if (!fs.existsSync(dbPath()))
177
+ return;
178
+ db = new Database(dbPath(), { fileMustExist: true, timeout: 200 });
179
+ countUse(db, name);
180
+ }
181
+ catch {
182
+ /* uncounted */
183
+ }
184
+ finally {
185
+ db?.close();
186
+ }
187
+ }
188
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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"}
@@ -118,6 +118,10 @@ export const setConfig = {
118
118
  .boolean()
119
119
  .optional()
120
120
  .describe('Whether Eklavya updates itself in the background at session start (default true). Global scope only.'),
121
+ telemetry: z
122
+ .boolean()
123
+ .optional()
124
+ .describe('Whether Eklavya sends its anonymous daily usage counts (default true). Global scope only. "Turn off Eklavya analytics" means telemetry:false.'),
121
125
  domains_enabled: z.array(z.string()).optional(),
122
126
  // The namespaced half. Passed as objects rather than as dotted keys because
123
127
  // the schema is what the model reads: a `memory` object with named fields
@@ -1 +1 @@
1
- {"version":3,"file":"config_tools.js","sourceRoot":"","sources":["../../src/tools/config_tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config_tools.js","sourceRoot":"","sources":["../../src/tools/config_tools.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ import { codeFindSymbol, codeOutline } from './code_tools.js';
11
11
  import { memoryCollections } from './collection_tools.js';
12
12
  import { memoryFileHistory, memoryGet, memorySearch, memoryStatus, memoryTimeline, } from './memory_read_tools.js';
13
13
  import { memoryCorrect, memoryDelete, memoryWrite } from './memory_write_tools.js';
14
+ import { countUse } from '../telemetry.js';
14
15
  export const TOOLS = [
15
16
  getLearnerProfile,
16
17
  logSessionConcepts,
@@ -44,6 +45,7 @@ export function registerTools(server, db) {
44
45
  server.registerTool(tool.name, { title: tool.title, description: tool.description, inputSchema: tool.inputSchema }, async (args) => {
45
46
  try {
46
47
  // Safe to retry: a busy transaction has already rolled back.
48
+ countUse(db, `tool:${tool.name}`);
47
49
  return toResult(retryOnBusy(() => tool.handler(args, { db })));
48
50
  }
49
51
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEnF,MAAM,CAAC,MAAM,KAAK,GAAc;IAC9B,iBAAiB;IACjB,kBAAkB;IAClB,kBAAkB;IAClB,aAAa;IACb,aAAa;IACb,cAAc;IACd,eAAe;IACf,SAAS;IACT,SAAS;IACT,YAAY;IACZ,SAAS;IACT,cAAc;IACd,iBAAiB;IACjB,YAAY;IACZ,WAAW;IACX,aAAa;IACb,YAAY;IACZ,WAAW;IACX,cAAc;IACd,iBAAiB;CAClB,CAAC;AAEF,8FAA8F;AAC9F,SAAS,QAAQ,CAAC,OAAgB;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,IAAI,OAAO,CAAC;IACtF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAiB,EAAE,EAAM;IACrD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,YAAY,CACjB,IAAI,CAAC,IAAI,EACT,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,EACnF,KAAK,EAAE,IAAa,EAAE,EAAE;YACtB,IAAI,CAAC;gBACH,6DAA6D;gBAC7D,OAAO,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;YACjE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,6DAA6D;gBAC7D,OAAO,QAAQ,CAAC;oBACd,KAAK,EAAE,aAAa;oBACpB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACzD,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,CAAC,MAAM,KAAK,GAAc;IAC9B,iBAAiB;IACjB,kBAAkB;IAClB,kBAAkB;IAClB,aAAa;IACb,aAAa;IACb,cAAc;IACd,eAAe;IACf,SAAS;IACT,SAAS;IACT,YAAY;IACZ,SAAS;IACT,cAAc;IACd,iBAAiB;IACjB,YAAY;IACZ,WAAW;IACX,aAAa;IACb,YAAY;IACZ,WAAW;IACX,cAAc;IACd,iBAAiB;CAClB,CAAC;AAEF,8FAA8F;AAC9F,SAAS,QAAQ,CAAC,OAAgB;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,IAAI,OAAO,CAAC;IACtF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAiB,EAAE,EAAM;IACrD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,YAAY,CACjB,IAAI,CAAC,IAAI,EACT,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,EACnF,KAAK,EAAE,IAAa,EAAE,EAAE;YACtB,IAAI,CAAC;gBACH,6DAA6D;gBAC7D,QAAQ,CAAC,EAAE,EAAE,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAClC,OAAO,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;YACjE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,6DAA6D;gBAC7D,OAAO,QAAQ,CAAC;oBACd,KAAK,EAAE,aAAa;oBACpB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACzD,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -12,7 +12,7 @@ searchable observations it can hand back to the agent weeks later.
12
12
  and tracks mastery with spaced repetition.
13
13
 
14
14
  Both halves are local by default: the summariser and the search index run on
15
- this machine and nothing leaves it unless `providers.observer` has been
15
+ this machine and no work leaves it unless `providers.observer` has been
16
16
  configured — an explicit choice that sends session batches to a Claude model
17
17
  through `claude -p`, on the developer's own Claude subscription.
18
18
 
@@ -163,7 +163,7 @@ eklavya config get # the effective config, and which file each half came fro
163
163
  eklavya db-path # where the history lives
164
164
  eklavya memory status # is capture healthy: entries, queue, pause reason, worker pid/job, provider, savings
165
165
  eklavya memory stop # end the running worker and its claude call; the job goes back to the queue
166
- eklavya memory backlog # unfinished jobs by project; `quarantine|discard|restore --helpers` for the 1.24.0 loop's noise
166
+ eklavya memory backlog # unfinished jobs by project; `discard --helpers` deletes the 1.24.0 loop's noise, memories included
167
167
  ```
168
168
 
169
169
  ## The memory half
@@ -237,6 +237,13 @@ row says the same. Never suggest `npm install -g eklavya` for an update: the
237
237
  `eklavya` command already runs the newer runtime's copy on its own.
238
238
  `auto_update false` turns updates off, globally only.
239
239
 
240
+ **Analytics.** Eklavya sends anonymous daily usage counts (numbers and setting
241
+ values, never paths, names or text) unless turned off. "Turn off Eklavya
242
+ analytics / telemetry / tracking" means `eklavya telemetry off`, or `set_config`
243
+ with `telemetry: false` at global scope. `eklavya telemetry show` prints
244
+ exactly what is sent; `eklavya telemetry` says whether it is on and why. The
245
+ full field list is https://eklavya-run.web.app/docs/usage-analytics/.
246
+
240
247
  Restarting Claude Code is what picks up a repaired install — the plugin and MCP
241
248
  server are read at session start. There is no background process to restart.
242
249
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eklavya",
3
- "version": "1.29.0",
3
+ "version": "1.30.0",
4
4
  "description": "Learn while your agent works — local knowledge graph, spaced repetition, and quiz gating for agent-assisted development.",
5
5
  "license": "MIT",
6
6
  "repository": {