@withone/cli 1.45.1 → 1.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -564,6 +564,18 @@ export ONE_NO_AUTO_UPDATE=1
564
564
 
565
565
  Run `one update` manually whenever you want to upgrade.
566
566
 
567
+ ### Telemetry
568
+
569
+ The CLI collects **usage analytics** — which command was run, the CLI version, OS/arch, and whether it ran in `--agent` mode — to help us prioritize improvements. Events are linked to your One account (user id, email, name, org) so they line up with your dashboard activity. **Command arguments, inputs, connection data, and secrets are never collected** (only the command name, e.g. `actions execute`). A one-time notice is shown on first run. Events are queued locally and sent in the background, so telemetry never slows down or blocks a command.
570
+
571
+ To opt out, set any of:
572
+
573
+ ```bash
574
+ export ONE_NO_TELEMETRY=1 # also accepted: ONE_DISABLE_TELEMETRY=1, or the cross-tool standard DO_NOT_TRACK=1
575
+ ```
576
+
577
+ Telemetry is also disabled automatically when `CI=1`. You can persist the choice by adding `"telemetry": "off"` to `~/.one/config.json`.
578
+
567
579
  ### Project config (`.onerc`)
568
580
 
569
581
  Drop a `.onerc` file in your project root to override global settings per-project. Simple `KEY=VALUE` format; `#` for comments. Read from the current working directory (no parent lookup).
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  getMemoryConfigOrDefault
3
- } from "./chunk-77564KWS.js";
3
+ } from "./chunk-BKD7A42U.js";
4
4
  import {
5
5
  getOpenAiApiKey,
6
6
  readConfig
7
- } from "./chunk-TVIZC7AC.js";
7
+ } from "./chunk-OEN5DNG7.js";
8
8
 
9
9
  // src/lib/output.ts
10
10
  import * as p from "@clack/prompts";
@@ -3,7 +3,7 @@ import {
3
3
  readConfig,
4
4
  setOpenAiApiKey,
5
5
  writeConfig
6
- } from "./chunk-TVIZC7AC.js";
6
+ } from "./chunk-OEN5DNG7.js";
7
7
 
8
8
  // src/lib/memory/config.ts
9
9
  var DEFAULT_MEMORY_CONFIG = {
@@ -3,10 +3,10 @@ import {
3
3
  isAgentMode,
4
4
  json,
5
5
  requireMemoryInit
6
- } from "./chunk-KH4ERRJ5.js";
6
+ } from "./chunk-56QOOA5V.js";
7
7
  import {
8
8
  getBackend
9
- } from "./chunk-TGWQUBKA.js";
9
+ } from "./chunk-GIMKPA2J.js";
10
10
 
11
11
  // src/commands/mem/sql.ts
12
12
  async function memSqlCommand(sql) {
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-44CV5IMX.js";
5
5
  import {
6
6
  getCacheTtl
7
- } from "./chunk-TVIZC7AC.js";
7
+ } from "./chunk-OEN5DNG7.js";
8
8
 
9
9
  // src/lib/flow-runner.ts
10
10
  import fs3 from "fs";
@@ -1271,7 +1271,7 @@ async function executeSubflowStep(step, context, api, permissions, allowedAction
1271
1271
  if (flowStack.includes(resolvedKey)) {
1272
1272
  throw new Error(`Circular flow detected: ${[...flowStack, resolvedKey].join(" \u2192 ")}`);
1273
1273
  }
1274
- const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-6KN2ZVXB.js");
1274
+ const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-VIKPVLBL.js");
1275
1275
  const { flow: subFlow, rootDir: subRootDir } = loadFlowWithMeta2(resolvedKey);
1276
1276
  const subContext = await executeFlow(
1277
1277
  subFlow,
@@ -5,10 +5,10 @@ import {
5
5
  getMemoryConfig,
6
6
  getMemoryConfigOrDefault,
7
7
  updateMemoryConfig
8
- } from "./chunk-77564KWS.js";
8
+ } from "./chunk-BKD7A42U.js";
9
9
  import {
10
10
  getOpenAiApiKey
11
- } from "./chunk-TVIZC7AC.js";
11
+ } from "./chunk-OEN5DNG7.js";
12
12
 
13
13
  // src/lib/memory/schema.ts
14
14
  var SCHEMA_VERSION = "2.1.0";
@@ -6,11 +6,11 @@ import {
6
6
  note,
7
7
  okJson,
8
8
  requireMemoryInit
9
- } from "./chunk-KH4ERRJ5.js";
9
+ } from "./chunk-56QOOA5V.js";
10
10
  import {
11
11
  getBackend,
12
12
  upsertRecord
13
- } from "./chunk-TGWQUBKA.js";
13
+ } from "./chunk-GIMKPA2J.js";
14
14
 
15
15
  // src/commands/mem/migrate.ts
16
16
  import fs4 from "fs";
@@ -2,6 +2,7 @@
2
2
  import fs from "fs";
3
3
  import path from "path";
4
4
  import os from "os";
5
+ import { randomUUID } from "crypto";
5
6
  function configDir() {
6
7
  return path.join(os.homedir(), ".one");
7
8
  }
@@ -241,6 +242,67 @@ async function ensureWhoAmI(api) {
241
242
  function getEnvFromApiKey(apiKey) {
242
243
  return apiKey.startsWith("sk_test_") ? "test" : "live";
243
244
  }
245
+ function deviceIdFile() {
246
+ return path.join(configDir(), "device-id");
247
+ }
248
+ function telemetryNoticeFile() {
249
+ return path.join(configDir(), ".telemetry-notice");
250
+ }
251
+ function getDeviceId() {
252
+ try {
253
+ const existing = fs.readFileSync(deviceIdFile(), "utf-8").trim();
254
+ if (existing) return existing;
255
+ } catch {
256
+ }
257
+ const id = randomUUID();
258
+ try {
259
+ if (!fs.existsSync(configDir())) fs.mkdirSync(configDir(), { mode: 448 });
260
+ fs.writeFileSync(deviceIdFile(), id, { mode: 384 });
261
+ } catch {
262
+ }
263
+ return id;
264
+ }
265
+ function telemetryNoticeShown() {
266
+ return fs.existsSync(telemetryNoticeFile());
267
+ }
268
+ function markTelemetryNoticeShown() {
269
+ try {
270
+ if (!fs.existsSync(configDir())) fs.mkdirSync(configDir(), { mode: 448 });
271
+ fs.writeFileSync(telemetryNoticeFile(), (/* @__PURE__ */ new Date()).toISOString(), { mode: 384 });
272
+ } catch {
273
+ }
274
+ }
275
+ function analyticsQueueFile() {
276
+ return path.join(configDir(), ".analytics-queue.jsonl");
277
+ }
278
+ var ANALYTICS_QUEUE_MAX = 500;
279
+ function appendAnalyticsQueue(line) {
280
+ try {
281
+ if (!fs.existsSync(configDir())) fs.mkdirSync(configDir(), { mode: 448 });
282
+ fs.appendFileSync(analyticsQueueFile(), `${line}
283
+ `, { mode: 384 });
284
+ } catch {
285
+ }
286
+ }
287
+ function readAnalyticsQueue() {
288
+ try {
289
+ return fs.readFileSync(analyticsQueueFile(), "utf-8").split("\n").filter(Boolean);
290
+ } catch {
291
+ return [];
292
+ }
293
+ }
294
+ function writeAnalyticsQueue(lines) {
295
+ try {
296
+ if (lines.length === 0) {
297
+ fs.rmSync(analyticsQueueFile(), { force: true });
298
+ return;
299
+ }
300
+ if (!fs.existsSync(configDir())) fs.mkdirSync(configDir(), { mode: 448 });
301
+ fs.writeFileSync(analyticsQueueFile(), `${lines.slice(-ANALYTICS_QUEUE_MAX).join("\n")}
302
+ `, { mode: 384 });
303
+ } catch {
304
+ }
305
+ }
244
306
 
245
307
  export {
246
308
  getProjectRoot,
@@ -266,5 +328,11 @@ export {
266
328
  getWhoAmI,
267
329
  updateWhoAmI,
268
330
  ensureWhoAmI,
269
- getEnvFromApiKey
331
+ getEnvFromApiKey,
332
+ getDeviceId,
333
+ telemetryNoticeShown,
334
+ markTelemetryNoticeShown,
335
+ appendAnalyticsQueue,
336
+ readAnalyticsQueue,
337
+ writeAnalyticsQueue
270
338
  };
@@ -2,8 +2,8 @@ import {
2
2
  defaultSearchableText,
3
3
  embed,
4
4
  embedBatch
5
- } from "./chunk-77564KWS.js";
6
- import "./chunk-TVIZC7AC.js";
5
+ } from "./chunk-BKD7A42U.js";
6
+ import "./chunk-OEN5DNG7.js";
7
7
  export {
8
8
  defaultSearchableText,
9
9
  embed,
@@ -11,9 +11,9 @@ import {
11
11
  saveFlow,
12
12
  summarizeFlowInputs,
13
13
  walkSteps
14
- } from "./chunk-DZK56R5R.js";
14
+ } from "./chunk-GDKMOLZ5.js";
15
15
  import "./chunk-44CV5IMX.js";
16
- import "./chunk-TVIZC7AC.js";
16
+ import "./chunk-OEN5DNG7.js";
17
17
  export {
18
18
  FlowRunner,
19
19
  collectStepTypes,
package/dist/index.js CHANGED
@@ -30,10 +30,10 @@ import {
30
30
  searchCachePath,
31
31
  validateActionInput,
32
32
  writeCache
33
- } from "./chunk-DZK56R5R.js";
33
+ } from "./chunk-GDKMOLZ5.js";
34
34
  import {
35
35
  memSqlCommand
36
- } from "./chunk-TLRJMJGU.js";
36
+ } from "./chunk-EDVE3BQZ.js";
37
37
  import {
38
38
  countRecords,
39
39
  deleteDatabase,
@@ -58,7 +58,7 @@ import {
58
58
  upsertRecords,
59
59
  writeDraftProfile,
60
60
  writeProfile
61
- } from "./chunk-Z4HKASJT.js";
61
+ } from "./chunk-MQU7UK5J.js";
62
62
  import {
63
63
  getByDotPath
64
64
  } from "./chunk-44CV5IMX.js";
@@ -81,7 +81,7 @@ import {
81
81
  semanticSearchUpgradeHint,
82
82
  semanticSearchUpgradeLine,
83
83
  setAgentMode
84
- } from "./chunk-KH4ERRJ5.js";
84
+ } from "./chunk-56QOOA5V.js";
85
85
  import {
86
86
  SCHEMA_VERSION,
87
87
  addRecord,
@@ -91,7 +91,7 @@ import {
91
91
  listBackendPlugins,
92
92
  loadBackendFromConfig,
93
93
  upsertRecord
94
- } from "./chunk-TGWQUBKA.js";
94
+ } from "./chunk-GIMKPA2J.js";
95
95
  import {
96
96
  DEFAULT_MEMORY_CONFIG,
97
97
  defaultSearchableText,
@@ -101,14 +101,16 @@ import {
101
101
  memoryConfigExists,
102
102
  setOpenAiApiKey,
103
103
  updateMemoryConfig
104
- } from "./chunk-77564KWS.js";
104
+ } from "./chunk-BKD7A42U.js";
105
105
  import {
106
+ appendAnalyticsQueue,
106
107
  configExists,
107
108
  ensureWhoAmI,
108
109
  getAccessControl,
109
110
  getAccessControlFromAllSources,
110
111
  getApiBase,
111
112
  getApiKey,
113
+ getDeviceId,
112
114
  getEnvFromApiKey,
113
115
  getGlobalConfigPath,
114
116
  getOpenAiApiKey,
@@ -116,19 +118,23 @@ import {
116
118
  getProjectRoot,
117
119
  getWhoAmI,
118
120
  globalConfigExists,
121
+ markTelemetryNoticeShown,
119
122
  projectConfigExists,
123
+ readAnalyticsQueue,
120
124
  readConfig,
121
125
  readGlobalConfig,
122
126
  readProjectConfig,
123
127
  resolveConfig,
128
+ telemetryNoticeShown,
124
129
  updateAccessControl,
125
130
  updateApiBase,
126
131
  updateWhoAmI,
132
+ writeAnalyticsQueue,
127
133
  writeConfig
128
- } from "./chunk-TVIZC7AC.js";
134
+ } from "./chunk-OEN5DNG7.js";
129
135
 
130
136
  // src/cli.ts
131
- import { createRequire as createRequire2 } from "module";
137
+ import { createRequire as createRequire3 } from "module";
132
138
  import path11 from "path";
133
139
  import { Command } from "commander";
134
140
 
@@ -1018,25 +1024,25 @@ async function loginCommand() {
1018
1024
  let targetScope = "global";
1019
1025
  const existingKey = getApiKey();
1020
1026
  if (existingKey) {
1021
- const pc14 = (await import("picocolors")).default;
1027
+ const pc15 = (await import("picocolors")).default;
1022
1028
  const resolved2 = resolveConfig();
1023
1029
  const whoami2 = resolved2.config?.whoami;
1024
1030
  const env2 = getEnvFromApiKey(existingKey);
1025
- const envLabel2 = env2 === "test" ? pc14.yellow("test") : pc14.green("live");
1026
- const currentScope = resolved2.scope === "project" ? pc14.cyan("local config") : pc14.magenta("global config");
1031
+ const envLabel2 = env2 === "test" ? pc15.yellow("test") : pc15.green("live");
1032
+ const currentScope = resolved2.scope === "project" ? pc15.cyan("local config") : pc15.magenta("global config");
1027
1033
  const lines = ["You are already logged in.", ""];
1028
1034
  if (whoami2) {
1029
1035
  const contextParts2 = [];
1030
1036
  if (whoami2.organization) contextParts2.push(whoami2.organization.name);
1031
1037
  if (whoami2.project) contextParts2.push(whoami2.project.name);
1032
1038
  const scopeDisplay2 = contextParts2.length > 0 ? contextParts2.join(" / ") : "Personal";
1033
- lines.push(`${pc14.bold(scopeDisplay2)} ${pc14.dim("\xB7")} ${envLabel2}`);
1034
- lines.push(`${whoami2.user.name} ${pc14.dim(`(${whoami2.user.email})`)}`);
1035
- if (whoami2.organization) lines.push(`${pc14.dim("Org:")} ${whoami2.organization.name}`);
1036
- if (whoami2.project) lines.push(`${pc14.dim("Project:")} ${whoami2.project.name}`);
1039
+ lines.push(`${pc15.bold(scopeDisplay2)} ${pc15.dim("\xB7")} ${envLabel2}`);
1040
+ lines.push(`${whoami2.user.name} ${pc15.dim(`(${whoami2.user.email})`)}`);
1041
+ if (whoami2.organization) lines.push(`${pc15.dim("Org:")} ${whoami2.organization.name}`);
1042
+ if (whoami2.project) lines.push(`${pc15.dim("Project:")} ${whoami2.project.name}`);
1037
1043
  }
1038
1044
  lines.push("");
1039
- lines.push(`${pc14.dim("Stored in")} ${currentScope}`);
1045
+ lines.push(`${pc15.dim("Stored in")} ${currentScope}`);
1040
1046
  p2.note(lines.join("\n"));
1041
1047
  const scopeChoice = await p2.select({
1042
1048
  message: "Where would you like to log in?",
@@ -1059,40 +1065,40 @@ async function loginCommand() {
1059
1065
  if (resolved.config) {
1060
1066
  writeConfig({ ...resolved.config, whoami }, targetScope);
1061
1067
  }
1062
- const pc13 = (await import("picocolors")).default;
1068
+ const pc14 = (await import("picocolors")).default;
1063
1069
  const env = getEnvFromApiKey(apiKey);
1064
1070
  const contextParts = [];
1065
1071
  if (whoami.organization) contextParts.push(whoami.organization.name);
1066
1072
  if (whoami.project) contextParts.push(whoami.project.name);
1067
1073
  const scopeDisplay = contextParts.length > 0 ? contextParts.join(" / ") : "Personal";
1068
- const envLabel = env === "test" ? pc13.yellow("test") : pc13.green("live");
1069
- const configLabel = targetScope === "project" ? pc13.cyan("local config") : pc13.magenta("global config");
1074
+ const envLabel = env === "test" ? pc14.yellow("test") : pc14.green("live");
1075
+ const configLabel = targetScope === "project" ? pc14.cyan("local config") : pc14.magenta("global config");
1070
1076
  const infoLines = [
1071
- `${pc13.bold(scopeDisplay)} ${pc13.dim("\xB7")} ${envLabel}`,
1072
- `${whoami.user.name} ${pc13.dim(`(${whoami.user.email})`)}`
1077
+ `${pc14.bold(scopeDisplay)} ${pc14.dim("\xB7")} ${envLabel}`,
1078
+ `${whoami.user.name} ${pc14.dim(`(${whoami.user.email})`)}`
1073
1079
  ];
1074
- if (whoami.organization) infoLines.push(`${pc13.dim("Org:")} ${whoami.organization.name}`);
1075
- if (whoami.project) infoLines.push(`${pc13.dim("Project:")} ${whoami.project.name}`);
1080
+ if (whoami.organization) infoLines.push(`${pc14.dim("Org:")} ${whoami.organization.name}`);
1081
+ if (whoami.project) infoLines.push(`${pc14.dim("Project:")} ${whoami.project.name}`);
1076
1082
  infoLines.push("");
1077
- infoLines.push(`${pc13.dim("Stored in")} ${configLabel}`);
1083
+ infoLines.push(`${pc14.dim("Stored in")} ${configLabel}`);
1078
1084
  p2.note(infoLines.join("\n"), "Logged in");
1079
1085
  console.log();
1080
- console.log(` ${pc13.dim("Next steps:")}`);
1081
- console.log(` ${pc13.cyan("one add <platform>")} ${pc13.dim("\u2014")} Connect a platform (e.g. gmail, slack, stripe)`);
1086
+ console.log(` ${pc14.dim("Next steps:")}`);
1087
+ console.log(` ${pc14.cyan("one add <platform>")} ${pc14.dim("\u2014")} Connect a platform (e.g. gmail, slack, stripe)`);
1082
1088
  console.log();
1083
- console.log(pc13.bold(" Copy-paste this to your AI agent:"));
1089
+ console.log(pc14.bold(" Copy-paste this to your AI agent:"));
1084
1090
  console.log();
1085
- console.log(pc13.cyan(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
1086
- console.log(pc13.cyan(" \u2502"));
1087
- console.log(pc13.cyan(" \u2502 The One CLI (`one`) is now installed on this machine. It"));
1088
- console.log(pc13.cyan(" \u2502 lets you interact with 400+ third-party platforms (Gmail,"));
1089
- console.log(pc13.cyan(" \u2502 Slack, Shopify, HubSpot, Stripe, GitHub, etc.) through"));
1090
- console.log(pc13.cyan(" \u2502 their APIs. Whenever you need to interact with any"));
1091
- console.log(pc13.cyan(" \u2502 third-party platform or external service, use the `one`"));
1092
- console.log(pc13.cyan(" \u2502 skill. Please save this to your project instructions or"));
1093
- console.log(pc13.cyan(" \u2502 memory so you remember it in future conversations."));
1094
- console.log(pc13.cyan(" \u2502"));
1095
- console.log(pc13.cyan(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
1091
+ console.log(pc14.cyan(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
1092
+ console.log(pc14.cyan(" \u2502"));
1093
+ console.log(pc14.cyan(" \u2502 The One CLI (`one`) is now installed on this machine. It"));
1094
+ console.log(pc14.cyan(" \u2502 lets you interact with 400+ third-party platforms (Gmail,"));
1095
+ console.log(pc14.cyan(" \u2502 Slack, Shopify, HubSpot, Stripe, GitHub, etc.) through"));
1096
+ console.log(pc14.cyan(" \u2502 their APIs. Whenever you need to interact with any"));
1097
+ console.log(pc14.cyan(" \u2502 third-party platform or external service, use the `one`"));
1098
+ console.log(pc14.cyan(" \u2502 skill. Please save this to your project instructions or"));
1099
+ console.log(pc14.cyan(" \u2502 memory so you remember it in future conversations."));
1100
+ console.log(pc14.cyan(" \u2502"));
1101
+ console.log(pc14.cyan(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
1096
1102
  console.log();
1097
1103
  p2.outro("Happy building!");
1098
1104
  }
@@ -5720,7 +5726,7 @@ async function syncModel(api, profile, options) {
5720
5726
  updateModelState(platform, model, { status: "failed", pagesProcessed, lastCursor }),
5721
5727
  (async () => {
5722
5728
  try {
5723
- const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
5729
+ const { getBackend: getBackend2 } = await import("./runtime-ZN7NZILR.js");
5724
5730
  const backend = await getBackend2();
5725
5731
  await Promise.race([
5726
5732
  backend.close(),
@@ -6075,7 +6081,7 @@ async function syncModel(api, profile, options) {
6075
6081
  db.exec(`DROP TABLE IF EXISTS _seen_ids`);
6076
6082
  }
6077
6083
  if (options.toMemory !== false) {
6078
- const backend = await (await import("./runtime-3NDWRLXL.js")).getBackend();
6084
+ const backend = await (await import("./runtime-ZN7NZILR.js")).getBackend();
6079
6085
  const type = `${platform}/${model}`;
6080
6086
  const existing = await backend.listKeysByType(type);
6081
6087
  const sourcePrefix = `${type}:`;
@@ -6155,7 +6161,7 @@ async function syncModel(api, profile, options) {
6155
6161
  let statusCounts;
6156
6162
  if (options.toMemory !== false) {
6157
6163
  try {
6158
- const backend = await (await import("./runtime-3NDWRLXL.js")).getBackend();
6164
+ const backend = await (await import("./runtime-ZN7NZILR.js")).getBackend();
6159
6165
  const typeName = `${platform}/${model}`;
6160
6166
  const [active, archived] = await Promise.all([
6161
6167
  backend.count(typeName, { status: "active" }),
@@ -7788,7 +7794,7 @@ ${result.total} results`);
7788
7794
  }
7789
7795
  }
7790
7796
  async function syncSqlCommand(platformModel, sql) {
7791
- const { syncSqlCommand: runSyncSql } = await import("./sql-ZABEXIXW.js");
7797
+ const { syncSqlCommand: runSyncSql } = await import("./sql-YMHNH3DT.js");
7792
7798
  await runSyncSql(platformModel, sql);
7793
7799
  }
7794
7800
  async function syncDeleteCommand(platformModel, options) {
@@ -7866,7 +7872,7 @@ async function syncDeleteCommand(platformModel, options) {
7866
7872
  async function maybeAutoMigrateLegacy(platform, models) {
7867
7873
  const dbSize = getDatabaseSize(platform);
7868
7874
  if (!dbSize || dbSize === "0 B") return;
7869
- const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
7875
+ const { getBackend: getBackend2 } = await import("./runtime-ZN7NZILR.js");
7870
7876
  const backend = await getBackend2();
7871
7877
  let memoryHasData = false;
7872
7878
  for (const model of models) {
@@ -7882,7 +7888,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
7882
7888
  ` detected legacy .one/sync/data/${platform}.db (${dbSize}) \u2014 auto-migrating into memory before sync.
7883
7889
  `
7884
7890
  );
7885
- const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-VV3VOXWJ.js");
7891
+ const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-SJXHOA2G.js");
7886
7892
  await memMigrateCommand3({ platform, yes: true });
7887
7893
  return;
7888
7894
  }
@@ -7891,7 +7897,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
7891
7897
  initialValue: true
7892
7898
  });
7893
7899
  if (p7.isCancel(shouldMigrate) || !shouldMigrate) return;
7894
- const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-VV3VOXWJ.js");
7900
+ const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-SJXHOA2G.js");
7895
7901
  await memMigrateCommand2({ platform, yes: true });
7896
7902
  }
7897
7903
  async function syncSuggestSearchableCommand(platformModel, options = {}) {
@@ -7952,7 +7958,7 @@ async function syncSuggestSearchableCommand(platformModel, options = {}) {
7952
7958
  async function syncListCommand(platform) {
7953
7959
  const profiles = listProfiles(platform);
7954
7960
  const state = await readSyncState();
7955
- const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
7961
+ const { getBackend: getBackend2 } = await import("./runtime-ZN7NZILR.js");
7956
7962
  const backend = await getBackend2();
7957
7963
  const syncs = await Promise.all(profiles.map(async (p10) => {
7958
7964
  const modelState = state[p10.platform]?.[p10.model];
@@ -8870,7 +8876,7 @@ async function memDoctorCommand() {
8870
8876
  }
8871
8877
  if (cfg.embedding.provider === "openai") {
8872
8878
  try {
8873
- const { embed: embed2 } = await import("./embedding-C3E4EAQ7.js");
8879
+ const { embed: embed2 } = await import("./embedding-4T4VYFEI.js");
8874
8880
  const result = await embed2("connectivity check");
8875
8881
  checks.push({
8876
8882
  name: "OpenAI embedding provider reachable",
@@ -10608,20 +10614,20 @@ function buildWorkflowIdeas(connections) {
10608
10614
  // src/commands/logout.ts
10609
10615
  import fs12 from "fs";
10610
10616
  import * as p9 from "@clack/prompts";
10611
- function formatWhoami(config2, apiKey, pc13) {
10617
+ function formatWhoami(config2, apiKey, pc14) {
10612
10618
  const whoami = config2.whoami;
10613
10619
  const env = getEnvFromApiKey(apiKey);
10614
- const envLabel = env === "test" ? pc13.yellow("test") : pc13.green("live");
10620
+ const envLabel = env === "test" ? pc14.yellow("test") : pc14.green("live");
10615
10621
  const lines = [];
10616
10622
  if (whoami) {
10617
10623
  const contextParts = [];
10618
10624
  if (whoami.organization) contextParts.push(whoami.organization.name);
10619
10625
  if (whoami.project) contextParts.push(whoami.project.name);
10620
10626
  const scopeDisplay = contextParts.length > 0 ? contextParts.join(" / ") : "Personal";
10621
- lines.push(`${pc13.bold(scopeDisplay)} ${pc13.dim("\xB7")} ${envLabel}`);
10622
- lines.push(`${whoami.user.name} ${pc13.dim(`(${whoami.user.email})`)}`);
10627
+ lines.push(`${pc14.bold(scopeDisplay)} ${pc14.dim("\xB7")} ${envLabel}`);
10628
+ lines.push(`${whoami.user.name} ${pc14.dim(`(${whoami.user.email})`)}`);
10623
10629
  } else {
10624
- lines.push(`${pc13.dim("Key:")} ${apiKey.slice(0, 8)}... ${pc13.dim("\xB7")} ${envLabel}`);
10630
+ lines.push(`${pc14.dim("Key:")} ${apiKey.slice(0, 8)}... ${pc14.dim("\xB7")} ${envLabel}`);
10625
10631
  }
10626
10632
  return lines;
10627
10633
  }
@@ -10650,7 +10656,7 @@ async function logoutCommand() {
10650
10656
  json({ status: cleared ? "logged_out" : "not_logged_in", message: cleared ? "Credentials cleared." : "No config found." });
10651
10657
  return;
10652
10658
  }
10653
- const pc13 = (await import("picocolors")).default;
10659
+ const pc14 = (await import("picocolors")).default;
10654
10660
  const globalConfig = readGlobalConfig();
10655
10661
  const projectConfig = readProjectConfig();
10656
10662
  const hasGlobal = globalConfig?.apiKey != null;
@@ -10659,13 +10665,13 @@ async function logoutCommand() {
10659
10665
  if (hasGlobal && hasProject) {
10660
10666
  const infoLines = ["You are logged in with multiple configs.", ""];
10661
10667
  if (projectConfig) {
10662
- infoLines.push(`${pc13.cyan("Local config:")}`);
10663
- infoLines.push(...formatWhoami(projectConfig, projectConfig.apiKey, pc13));
10668
+ infoLines.push(`${pc14.cyan("Local config:")}`);
10669
+ infoLines.push(...formatWhoami(projectConfig, projectConfig.apiKey, pc14));
10664
10670
  infoLines.push("");
10665
10671
  }
10666
10672
  if (globalConfig) {
10667
- infoLines.push(`${pc13.magenta("Global config:")}`);
10668
- infoLines.push(...formatWhoami(globalConfig, globalConfig.apiKey, pc13));
10673
+ infoLines.push(`${pc14.magenta("Global config:")}`);
10674
+ infoLines.push(...formatWhoami(globalConfig, globalConfig.apiKey, pc14));
10669
10675
  }
10670
10676
  p9.note(infoLines.join("\n"));
10671
10677
  const choice = await p9.select({
@@ -10683,14 +10689,14 @@ async function logoutCommand() {
10683
10689
  targetScope = choice;
10684
10690
  } else if (hasProject) {
10685
10691
  const infoLines = ["You are logged in.", ""];
10686
- infoLines.push(`${pc13.dim("Stored in")} ${pc13.cyan("local config")}`);
10687
- infoLines.push(...formatWhoami(projectConfig, projectConfig.apiKey, pc13));
10692
+ infoLines.push(`${pc14.dim("Stored in")} ${pc14.cyan("local config")}`);
10693
+ infoLines.push(...formatWhoami(projectConfig, projectConfig.apiKey, pc14));
10688
10694
  p9.note(infoLines.join("\n"));
10689
10695
  targetScope = "project";
10690
10696
  } else if (hasGlobal) {
10691
10697
  const infoLines = ["You are logged in.", ""];
10692
- infoLines.push(`${pc13.dim("Stored in")} ${pc13.magenta("global config")}`);
10693
- infoLines.push(...formatWhoami(globalConfig, globalConfig.apiKey, pc13));
10698
+ infoLines.push(`${pc14.dim("Stored in")} ${pc14.magenta("global config")}`);
10699
+ infoLines.push(...formatWhoami(globalConfig, globalConfig.apiKey, pc14));
10694
10700
  p9.note(infoLines.join("\n"));
10695
10701
  targetScope = "global";
10696
10702
  } else {
@@ -10724,9 +10730,165 @@ async function logoutCommand() {
10724
10730
  p9.outro("Logged out.");
10725
10731
  }
10726
10732
 
10727
- // src/cli.ts
10733
+ // src/lib/analytics.ts
10734
+ import { createRequire as createRequire2 } from "module";
10735
+ import { randomUUID } from "crypto";
10736
+ import pc13 from "picocolors";
10728
10737
  var require3 = createRequire2(import.meta.url);
10729
- var { version } = require3("../package.json");
10738
+ var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com";
10739
+ var DEFAULT_POSTHOG_KEY = "phc_a9ok4w0uxiZcVoSWOISIlin85lHMXQD3vWPaYnuRlRV";
10740
+ var inFlight = /* @__PURE__ */ new Set();
10741
+ var delivered = /* @__PURE__ */ new Set();
10742
+ function posthogHost() {
10743
+ return process.env.ONE_POSTHOG_HOST || DEFAULT_POSTHOG_HOST;
10744
+ }
10745
+ function posthogKey() {
10746
+ return process.env.ONE_POSTHOG_KEY || DEFAULT_POSTHOG_KEY;
10747
+ }
10748
+ function cliVersion() {
10749
+ try {
10750
+ return require3("../package.json").version;
10751
+ } catch {
10752
+ return "unknown";
10753
+ }
10754
+ }
10755
+ function envName() {
10756
+ const key = getApiKey();
10757
+ return key ? getEnvFromApiKey(key) : "live";
10758
+ }
10759
+ function isOn(value) {
10760
+ return value === "1" || value === "true";
10761
+ }
10762
+ function debugLog(message) {
10763
+ if (isOn(process.env.ONE_ANALYTICS_DEBUG)) {
10764
+ process.stderr.write(`[analytics] ${message}
10765
+ `);
10766
+ }
10767
+ }
10768
+ function isTelemetryDisabled() {
10769
+ if (isOn(process.env.ONE_NO_TELEMETRY) || isOn(process.env.ONE_DISABLE_TELEMETRY)) return true;
10770
+ if (isOn(process.env.DO_NOT_TRACK)) return true;
10771
+ if (isOn(process.env.CI)) return true;
10772
+ if (readConfig()?.telemetry === "off") return true;
10773
+ return false;
10774
+ }
10775
+ function distinctId() {
10776
+ return getWhoAmI()?.user?.id ?? getDeviceId();
10777
+ }
10778
+ function baseProperties() {
10779
+ return {
10780
+ $lib: "one-cli",
10781
+ cli_version: cliVersion(),
10782
+ agent_mode: isAgentMode(),
10783
+ env: envName(),
10784
+ os: process.platform,
10785
+ arch: process.arch,
10786
+ node_version: process.versions.node
10787
+ };
10788
+ }
10789
+ function personSet() {
10790
+ const whoami = getWhoAmI();
10791
+ if (!whoami?.user) return void 0;
10792
+ const set = {};
10793
+ if (whoami.user.email) set.email = whoami.user.email;
10794
+ if (whoami.user.name) set.name = whoami.user.name;
10795
+ if (whoami.organization?.id) set.organization_id = whoami.organization.id;
10796
+ return Object.keys(set).length ? set : void 0;
10797
+ }
10798
+ function send(item) {
10799
+ const insertId = item.properties.$insert_id;
10800
+ const controller = new AbortController();
10801
+ inFlight.add(controller);
10802
+ void (async () => {
10803
+ try {
10804
+ const res = await fetch(`${posthogHost()}/i/v0/e/`, {
10805
+ method: "POST",
10806
+ headers: { "Content-Type": "application/json" },
10807
+ body: JSON.stringify({
10808
+ api_key: posthogKey(),
10809
+ event: item.event,
10810
+ distinct_id: item.distinct_id,
10811
+ properties: item.properties,
10812
+ timestamp: item.timestamp
10813
+ }),
10814
+ signal: controller.signal
10815
+ });
10816
+ if (res.ok && insertId) delivered.add(insertId);
10817
+ debugLog(`"${item.event}" -> HTTP ${res.status}${res.ok ? "" : " (retry next run)"}`);
10818
+ } catch (err) {
10819
+ debugLog(`"${item.event}" not sent: ${err instanceof Error ? err.message : String(err)} (retry next run)`);
10820
+ } finally {
10821
+ inFlight.delete(controller);
10822
+ }
10823
+ })();
10824
+ }
10825
+ function capture(event, properties = {}) {
10826
+ if (isTelemetryDisabled()) {
10827
+ debugLog(`disabled \u2014 skipping "${event}"`);
10828
+ return;
10829
+ }
10830
+ const props = { ...baseProperties(), ...properties, $insert_id: randomUUID() };
10831
+ const set = personSet();
10832
+ if (set) props.$set = set;
10833
+ const item = {
10834
+ event,
10835
+ distinct_id: distinctId(),
10836
+ properties: props,
10837
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
10838
+ };
10839
+ appendAnalyticsQueue(JSON.stringify(item));
10840
+ }
10841
+ function captureCommand(command) {
10842
+ capture("CLI Command Run", { command: commandPath(command) });
10843
+ }
10844
+ function commandPath(command) {
10845
+ const parts = [];
10846
+ let current = command;
10847
+ while (current && current.name() && current.name() !== "one") {
10848
+ parts.unshift(current.name());
10849
+ current = current.parent;
10850
+ }
10851
+ return parts.join(" ") || command.name();
10852
+ }
10853
+ function drainQueue() {
10854
+ if (isTelemetryDisabled()) {
10855
+ writeAnalyticsQueue([]);
10856
+ return;
10857
+ }
10858
+ for (const line of readAnalyticsQueue()) {
10859
+ try {
10860
+ const item = JSON.parse(line);
10861
+ if (item?.properties?.$insert_id) send(item);
10862
+ } catch {
10863
+ }
10864
+ }
10865
+ }
10866
+ function flush() {
10867
+ for (const controller of inFlight) controller.abort();
10868
+ const remaining = readAnalyticsQueue().filter((line) => {
10869
+ try {
10870
+ const id = JSON.parse(line).properties?.$insert_id;
10871
+ return id ? !delivered.has(id) : false;
10872
+ } catch {
10873
+ return false;
10874
+ }
10875
+ });
10876
+ writeAnalyticsQueue(remaining);
10877
+ }
10878
+ function maybeShowTelemetryNotice() {
10879
+ if (isTelemetryDisabled() || isAgentMode()) return;
10880
+ if (telemetryNoticeShown()) return;
10881
+ markTelemetryNoticeShown();
10882
+ process.stderr.write(
10883
+ pc13.dim(
10884
+ "One CLI collects usage analytics (which commands run, linked to your One account) to improve the product.\nNo arguments, inputs, or secrets are ever collected. Opt out anytime with ONE_NO_TELEMETRY=1.\n"
10885
+ )
10886
+ );
10887
+ }
10888
+
10889
+ // src/cli.ts
10890
+ var require4 = createRequire3(import.meta.url);
10891
+ var { version } = require4("../package.json");
10730
10892
  var program = new Command();
10731
10893
  program.name("one").option("--agent", "Machine-readable JSON output (no colors, spinners, or prompts)").description(`One CLI \u2014 Connect AI agents to 400+ platforms through one interface.
10732
10894
 
@@ -10802,11 +10964,14 @@ program.name("one").option("--agent", "Machine-readable JSON output (no colors,
10802
10964
  Platform names are lowercase; multi-word names use dashes (e.g. hubspot, ship-station, google-calendar).
10803
10965
  Run 'one platforms' to browse all 400+ available platforms.`).version(version);
10804
10966
  var updateCheckPromise;
10805
- program.hook("preAction", (thisCommand) => {
10967
+ program.hook("preAction", (thisCommand, actionCommand) => {
10806
10968
  const opts = program.opts();
10807
10969
  if (opts.agent) {
10808
10970
  setAgentMode(true);
10809
10971
  }
10972
+ maybeShowTelemetryNotice();
10973
+ captureCommand(actionCommand);
10974
+ drainQueue();
10810
10975
  const commandName = thisCommand.args?.[0];
10811
10976
  if (commandName !== "update") {
10812
10977
  updateCheckPromise = checkLatestVersionCached();
@@ -10820,6 +10985,7 @@ program.hook("preAction", (thisCommand) => {
10820
10985
  });
10821
10986
  program.hook("postAction", async () => {
10822
10987
  await closeBackendIfCached();
10988
+ flush();
10823
10989
  if (!updateCheckPromise) return;
10824
10990
  const info = await updateCheckPromise;
10825
10991
  if (!info) return;
@@ -11138,21 +11304,21 @@ program.command("whoami").description("Show the user, organization, and project
11138
11304
  });
11139
11305
  return;
11140
11306
  }
11141
- const pc13 = (await import("picocolors")).default;
11307
+ const pc14 = (await import("picocolors")).default;
11142
11308
  const contextParts = [];
11143
11309
  if (whoami.organization) contextParts.push(whoami.organization.name);
11144
11310
  if (whoami.project) contextParts.push(whoami.project.name);
11145
11311
  const scopeDisplay = contextParts.length > 0 ? contextParts.join(" / ") : "Personal";
11146
- const envLabel = env === "test" ? pc13.yellow("test") : pc13.green("live");
11147
- const configLabel = configScope === "project" ? pc13.cyan("project config") : pc13.magenta("global config");
11312
+ const envLabel = env === "test" ? pc14.yellow("test") : pc14.green("live");
11313
+ const configLabel = configScope === "project" ? pc14.cyan("project config") : pc14.magenta("global config");
11148
11314
  console.log();
11149
- console.log(` ${pc13.bold(scopeDisplay)} ${pc13.dim("\xB7")} ${envLabel}`);
11150
- console.log(` ${whoami.user.name} ${pc13.dim(`(${whoami.user.email})`)}`);
11151
- if (whoami.organization) console.log(` ${pc13.dim("Org:")} ${whoami.organization.name} ${pc13.dim(`(${whoami.organization.id})`)}`);
11152
- if (whoami.project) console.log(` ${pc13.dim("Project:")} ${whoami.project.name} ${pc13.dim(`(${whoami.project.id})`)}`);
11315
+ console.log(` ${pc14.bold(scopeDisplay)} ${pc14.dim("\xB7")} ${envLabel}`);
11316
+ console.log(` ${whoami.user.name} ${pc14.dim(`(${whoami.user.email})`)}`);
11317
+ if (whoami.organization) console.log(` ${pc14.dim("Org:")} ${whoami.organization.name} ${pc14.dim(`(${whoami.organization.id})`)}`);
11318
+ if (whoami.project) console.log(` ${pc14.dim("Project:")} ${whoami.project.name} ${pc14.dim(`(${whoami.project.id})`)}`);
11153
11319
  console.log();
11154
- console.log(` ${pc13.dim("Using")} ${configLabel}`);
11155
- console.log(` ${pc13.dim("API:")} ${apiBase}`);
11320
+ console.log(` ${pc14.dim("Using")} ${configLabel}`);
11321
+ console.log(` ${pc14.dim("API:")} ${apiBase}`);
11156
11322
  console.log();
11157
11323
  });
11158
11324
  program.command("add [platform]").description("Shortcut for: connection add").action(async (platform) => {
@@ -3,12 +3,12 @@ import {
3
3
  dotPathToJsonbExpr,
4
4
  memMigrateCommand,
5
5
  reviveStringifiedJson
6
- } from "./chunk-Z4HKASJT.js";
6
+ } from "./chunk-MQU7UK5J.js";
7
7
  import "./chunk-44CV5IMX.js";
8
- import "./chunk-KH4ERRJ5.js";
9
- import "./chunk-TGWQUBKA.js";
10
- import "./chunk-77564KWS.js";
11
- import "./chunk-TVIZC7AC.js";
8
+ import "./chunk-56QOOA5V.js";
9
+ import "./chunk-GIMKPA2J.js";
10
+ import "./chunk-BKD7A42U.js";
11
+ import "./chunk-OEN5DNG7.js";
12
12
  export {
13
13
  buildIdentityMap,
14
14
  dotPathToJsonbExpr,
@@ -4,9 +4,9 @@ import {
4
4
  getBackend,
5
5
  resetBackendSingleton,
6
6
  upsertRecord
7
- } from "./chunk-TGWQUBKA.js";
8
- import "./chunk-77564KWS.js";
9
- import "./chunk-TVIZC7AC.js";
7
+ } from "./chunk-GIMKPA2J.js";
8
+ import "./chunk-BKD7A42U.js";
9
+ import "./chunk-OEN5DNG7.js";
10
10
  export {
11
11
  addRecord,
12
12
  closeBackendIfCached,
@@ -0,0 +1,12 @@
1
+ import {
2
+ memSqlCommand,
3
+ syncSqlCommand
4
+ } from "./chunk-EDVE3BQZ.js";
5
+ import "./chunk-56QOOA5V.js";
6
+ import "./chunk-GIMKPA2J.js";
7
+ import "./chunk-BKD7A42U.js";
8
+ import "./chunk-OEN5DNG7.js";
9
+ export {
10
+ memSqlCommand,
11
+ syncSqlCommand
12
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withone/cli",
3
- "version": "1.45.1",
3
+ "version": "1.46.0",
4
4
  "description": "CLI for managing One",
5
5
  "type": "module",
6
6
  "files": [
@@ -1,12 +0,0 @@
1
- import {
2
- memSqlCommand,
3
- syncSqlCommand
4
- } from "./chunk-TLRJMJGU.js";
5
- import "./chunk-KH4ERRJ5.js";
6
- import "./chunk-TGWQUBKA.js";
7
- import "./chunk-77564KWS.js";
8
- import "./chunk-TVIZC7AC.js";
9
- export {
10
- memSqlCommand,
11
- syncSqlCommand
12
- };