@withone/cli 1.45.0 → 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
@@ -268,7 +268,7 @@ one actions execute stripe <actionId> <connectionKey> \
268
268
  | `--mock` | Return example response without making an API call |
269
269
  | `--skip-validation` | Skip input validation against the action schema |
270
270
  | `--output <path>` | Save response to a file (for binary downloads) |
271
- | `--no-cache` | Fetch action details fresh instead of from the local cache (execution itself is never cached) |
271
+ | `--no-cache` | Bypass the cached action details and re-fetch them; the fresh details still refresh the cache (execution itself is never cached) |
272
272
 
273
273
  The CLI validates required parameters (path variables, query params, body fields) against the action schema before executing. Missing params return a clear error with the flag name and description. Pass `--skip-validation` to bypass.
274
274
 
@@ -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";
@@ -672,29 +672,32 @@ function isActionDetailsEntry(entry) {
672
672
  }
673
673
  async function resolveActionDetails(api, actionId, opts = {}) {
674
674
  const useCache = opts.useCache !== false;
675
+ const warn = opts.warn ?? ((m) => {
676
+ process.stderr.write(m);
677
+ });
675
678
  const cachePath = knowledgeCachePath(actionId);
676
679
  const raw = useCache ? readCache(cachePath) : null;
677
680
  const cached = isActionDetailsEntry(raw) ? raw : null;
678
681
  if (cached && isFresh(cached)) {
679
- return { details: cached.data, cacheHit: true, entry: cached };
682
+ return { details: cached.data, cacheHit: true, stale: false, entry: cached };
680
683
  }
681
684
  try {
682
685
  const result = await api.getActionDetailsWithMeta(actionId, cached?.etag ?? void 0);
683
686
  if (result.status === 304 && cached) {
684
687
  cached.cachedAt = (/* @__PURE__ */ new Date()).toISOString();
685
688
  writeCache(cachePath, cached);
686
- return { details: cached.data, cacheHit: true, entry: cached };
689
+ return { details: cached.data, cacheHit: true, stale: false, entry: cached };
687
690
  }
688
691
  const entry = makeCacheEntry(actionId, result.data, result.etag);
689
692
  writeCache(cachePath, entry);
690
- return { details: result.data, cacheHit: false, entry };
693
+ return { details: result.data, cacheHit: false, stale: false, entry };
691
694
  } catch (fetchError) {
692
695
  if (cached) {
693
- process.stderr.write(
696
+ warn(
694
697
  `Warning: serving cached action details (network unavailable, cached ${formatAge(getAge(cached))} ago)
695
698
  `
696
699
  );
697
- return { details: cached.data, cacheHit: true, entry: cached };
700
+ return { details: cached.data, cacheHit: true, stale: true, entry: cached };
698
701
  }
699
702
  throw fetchError;
700
703
  }
@@ -1268,7 +1271,7 @@ async function executeSubflowStep(step, context, api, permissions, allowedAction
1268
1271
  if (flowStack.includes(resolvedKey)) {
1269
1272
  throw new Error(`Circular flow detected: ${[...flowStack, resolvedKey].join(" \u2192 ")}`);
1270
1273
  }
1271
- const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-FQVTF36N.js");
1274
+ const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-VIKPVLBL.js");
1272
1275
  const { flow: subFlow, rootDir: subRootDir } = loadFlowWithMeta2(resolvedKey);
1273
1276
  const subContext = await executeFlow(
1274
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-UXKF6AEG.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-UXKF6AEG.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
  }
@@ -2382,7 +2388,8 @@ async function actionsSearchCommand(platform, query, options) {
2382
2388
  try {
2383
2389
  const agentType = knowledgeAgent ? "knowledge" : options.type || "execute";
2384
2390
  const useCache = options.cache !== false;
2385
- const cachePath = searchCachePath(platform, query, agentType || "knowledge");
2391
+ const searchType = agentType || "knowledge";
2392
+ const cachePath = searchCachePath(platform, query, searchType);
2386
2393
  const cached = useCache ? readCache(cachePath) : null;
2387
2394
  let cleanedActions;
2388
2395
  let cacheHit = false;
@@ -2413,8 +2420,8 @@ async function actionsSearchCommand(platform, query, options) {
2413
2420
  path: action.path
2414
2421
  }));
2415
2422
  writeCache(cachePath, makeCacheEntry(
2416
- `${platform}_${query}_${agentType || "knowledge"}`,
2417
- { actions: cleanedActions },
2423
+ `${platform}_${query}_${searchType}`,
2424
+ { actions: cleanedActions, platform, query, searchType },
2418
2425
  result.etag
2419
2426
  ));
2420
2427
  }
@@ -2596,7 +2603,7 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
2596
2603
  }
2597
2604
  const api = new OneApi(apiKey, getApiBase());
2598
2605
  const spinner5 = createSpinner();
2599
- spinner5.start("Loading action details...");
2606
+ spinner5.start("Resolving action details...");
2600
2607
  try {
2601
2608
  const { details: actionDetails, cacheHit: preflightCacheHit } = await resolveActionDetails(api, actionId, { useCache: options.cache !== false });
2602
2609
  if (!isMethodAllowed(actionDetails.method, permissions)) {
@@ -2605,7 +2612,9 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
2605
2612
  `Method "${actionDetails.method}" is not allowed under "${permissions}" permission level.`
2606
2613
  );
2607
2614
  }
2608
- spinner5.stop(`Action: ${actionDetails.title} [${actionDetails.method}]`);
2615
+ spinner5.stop(
2616
+ `Action: ${actionDetails.title} [${actionDetails.method}]` + (preflightCacheHit ? pc6.dim(" (cached)") : "")
2617
+ );
2609
2618
  const data = options.data ? parseJsonArg2(options.data, "--data") : void 0;
2610
2619
  const pathVariables = options.pathVars ? parseJsonArg2(options.pathVars, "--path-vars") : void 0;
2611
2620
  const queryParams = options.queryParams ? parseJsonArg2(options.queryParams, "--query-params") : void 0;
@@ -2830,6 +2839,7 @@ async function actionsExecuteParallelCommand() {
2830
2839
  const api = new OneApi(apiKey, getApiBase());
2831
2840
  const prepared = [];
2832
2841
  const errors = [];
2842
+ const staleWarned = /* @__PURE__ */ new Set();
2833
2843
  for (let i = 0; i < segments.length; i++) {
2834
2844
  const seg = segments[i];
2835
2845
  const label = `${seg.platform}/${seg.actionId}`;
@@ -2843,7 +2853,14 @@ async function actionsExecuteParallelCommand() {
2843
2853
  let actionDetails;
2844
2854
  let preflightCacheHit = false;
2845
2855
  try {
2846
- const resolved = await resolveActionDetails(api, seg.actionId, { useCache: flags.useCache });
2856
+ const resolved = await resolveActionDetails(api, seg.actionId, {
2857
+ useCache: flags.useCache,
2858
+ warn: (msg) => {
2859
+ if (staleWarned.has(seg.actionId)) return;
2860
+ staleWarned.add(seg.actionId);
2861
+ process.stderr.write(msg);
2862
+ }
2863
+ });
2847
2864
  actionDetails = resolved.details;
2848
2865
  preflightCacheHit = resolved.cacheHit;
2849
2866
  } catch (err) {
@@ -5709,7 +5726,7 @@ async function syncModel(api, profile, options) {
5709
5726
  updateModelState(platform, model, { status: "failed", pagesProcessed, lastCursor }),
5710
5727
  (async () => {
5711
5728
  try {
5712
- const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
5729
+ const { getBackend: getBackend2 } = await import("./runtime-ZN7NZILR.js");
5713
5730
  const backend = await getBackend2();
5714
5731
  await Promise.race([
5715
5732
  backend.close(),
@@ -6064,7 +6081,7 @@ async function syncModel(api, profile, options) {
6064
6081
  db.exec(`DROP TABLE IF EXISTS _seen_ids`);
6065
6082
  }
6066
6083
  if (options.toMemory !== false) {
6067
- const backend = await (await import("./runtime-3NDWRLXL.js")).getBackend();
6084
+ const backend = await (await import("./runtime-ZN7NZILR.js")).getBackend();
6068
6085
  const type = `${platform}/${model}`;
6069
6086
  const existing = await backend.listKeysByType(type);
6070
6087
  const sourcePrefix = `${type}:`;
@@ -6144,7 +6161,7 @@ async function syncModel(api, profile, options) {
6144
6161
  let statusCounts;
6145
6162
  if (options.toMemory !== false) {
6146
6163
  try {
6147
- const backend = await (await import("./runtime-3NDWRLXL.js")).getBackend();
6164
+ const backend = await (await import("./runtime-ZN7NZILR.js")).getBackend();
6148
6165
  const typeName = `${platform}/${model}`;
6149
6166
  const [active, archived] = await Promise.all([
6150
6167
  backend.count(typeName, { status: "active" }),
@@ -7777,7 +7794,7 @@ ${result.total} results`);
7777
7794
  }
7778
7795
  }
7779
7796
  async function syncSqlCommand(platformModel, sql) {
7780
- const { syncSqlCommand: runSyncSql } = await import("./sql-ZABEXIXW.js");
7797
+ const { syncSqlCommand: runSyncSql } = await import("./sql-YMHNH3DT.js");
7781
7798
  await runSyncSql(platformModel, sql);
7782
7799
  }
7783
7800
  async function syncDeleteCommand(platformModel, options) {
@@ -7855,7 +7872,7 @@ async function syncDeleteCommand(platformModel, options) {
7855
7872
  async function maybeAutoMigrateLegacy(platform, models) {
7856
7873
  const dbSize = getDatabaseSize(platform);
7857
7874
  if (!dbSize || dbSize === "0 B") return;
7858
- const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
7875
+ const { getBackend: getBackend2 } = await import("./runtime-ZN7NZILR.js");
7859
7876
  const backend = await getBackend2();
7860
7877
  let memoryHasData = false;
7861
7878
  for (const model of models) {
@@ -7871,7 +7888,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
7871
7888
  ` detected legacy .one/sync/data/${platform}.db (${dbSize}) \u2014 auto-migrating into memory before sync.
7872
7889
  `
7873
7890
  );
7874
- const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-VV3VOXWJ.js");
7891
+ const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-SJXHOA2G.js");
7875
7892
  await memMigrateCommand3({ platform, yes: true });
7876
7893
  return;
7877
7894
  }
@@ -7880,7 +7897,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
7880
7897
  initialValue: true
7881
7898
  });
7882
7899
  if (p7.isCancel(shouldMigrate) || !shouldMigrate) return;
7883
- const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-VV3VOXWJ.js");
7900
+ const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-SJXHOA2G.js");
7884
7901
  await memMigrateCommand2({ platform, yes: true });
7885
7902
  }
7886
7903
  async function syncSuggestSearchableCommand(platformModel, options = {}) {
@@ -7941,7 +7958,7 @@ async function syncSuggestSearchableCommand(platformModel, options = {}) {
7941
7958
  async function syncListCommand(platform) {
7942
7959
  const profiles = listProfiles(platform);
7943
7960
  const state = await readSyncState();
7944
- const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
7961
+ const { getBackend: getBackend2 } = await import("./runtime-ZN7NZILR.js");
7945
7962
  const backend = await getBackend2();
7946
7963
  const syncs = await Promise.all(profiles.map(async (p10) => {
7947
7964
  const modelState = state[p10.platform]?.[p10.model];
@@ -8859,7 +8876,7 @@ async function memDoctorCommand() {
8859
8876
  }
8860
8877
  if (cfg.embedding.provider === "openai") {
8861
8878
  try {
8862
- const { embed: embed2 } = await import("./embedding-C3E4EAQ7.js");
8879
+ const { embed: embed2 } = await import("./embedding-4T4VYFEI.js");
8863
8880
  const result = await embed2("connectivity check");
8864
8881
  checks.push({
8865
8882
  name: "OpenAI embedding provider reachable",
@@ -9204,6 +9221,9 @@ async function cacheUpdateAllCommand() {
9204
9221
  error("Not configured. Run `one init` first.");
9205
9222
  }
9206
9223
  const api = new OneApi(apiKey, getApiBase());
9224
+ const ac = getAccessControlFromAllSources();
9225
+ const permissions = ac.permissions || "admin";
9226
+ const actionIds = ac.actionIds || ["*"];
9207
9227
  const entries = listCacheEntries();
9208
9228
  if (entries.length === 0) {
9209
9229
  if (isAgentMode()) {
@@ -9226,8 +9246,36 @@ async function cacheUpdateAllCommand() {
9226
9246
  writeCache(e.filePath, newEntry);
9227
9247
  updated++;
9228
9248
  } else {
9229
- const refreshed = { ...e.entry, cachedAt: (/* @__PURE__ */ new Date()).toISOString() };
9230
- writeCache(e.filePath, refreshed);
9249
+ const data = e.entry.data;
9250
+ if (data?.platform && data?.query) {
9251
+ const searchType = data.searchType ?? "knowledge";
9252
+ const result = await api.searchActionsWithMeta(
9253
+ data.platform,
9254
+ data.query,
9255
+ searchType,
9256
+ e.entry.etag ?? void 0
9257
+ );
9258
+ if (result.status === 304) {
9259
+ writeCache(e.filePath, { ...e.entry, cachedAt: (/* @__PURE__ */ new Date()).toISOString() });
9260
+ } else {
9261
+ let actions2 = result.data;
9262
+ actions2 = filterByPermissions(actions2, permissions);
9263
+ actions2 = actions2.filter((a) => isActionAllowed(a.systemId, actionIds));
9264
+ const cleaned = actions2.map((a) => ({
9265
+ actionId: a.systemId,
9266
+ title: a.title,
9267
+ method: a.method,
9268
+ path: a.path
9269
+ }));
9270
+ writeCache(e.filePath, makeCacheEntry(
9271
+ e.entry.key,
9272
+ { actions: cleaned, platform: data.platform, query: data.query, searchType },
9273
+ result.etag
9274
+ ));
9275
+ }
9276
+ } else {
9277
+ writeCache(e.filePath, { ...e.entry, cachedAt: (/* @__PURE__ */ new Date()).toISOString() });
9278
+ }
9231
9279
  updated++;
9232
9280
  }
9233
9281
  } catch (err) {
@@ -9313,7 +9361,7 @@ one --agent actions execute <platform> <actionId> <key> -d '{}' # Execute it
9313
9361
  - \`--mock\` \u2014 Return example response without making an API call (useful for building UI against a response shape)
9314
9362
  - \`--skip-validation\` \u2014 Skip input validation against the action schema
9315
9363
  - \`--output <path>\` \u2014 Save response to a file (for binary downloads like PDFs, images, documents)
9316
- - \`--no-cache\` \u2014 Fetch action details fresh instead of from the local cache (execution itself is never cached)
9364
+ - \`--no-cache\` \u2014 Bypass the cached action details and re-fetch them; the fresh details still refresh the cache (execution itself is never cached)
9317
9365
 
9318
9366
  The CLI validates required parameters against the action schema before executing. If you're missing a required path variable, query param, or body field, you'll get a clear error listing what's missing and which flag to use. Pass \`--skip-validation\` to bypass.
9319
9367
 
@@ -9439,7 +9487,7 @@ one --agent actions execute <platform> <actionId> <connectionKey> [options]
9439
9487
  - \`--mock\` \u2014 Return example response without making an API call
9440
9488
  - \`--skip-validation\` \u2014 Skip input validation against the action schema
9441
9489
  - \`--output <path>\` \u2014 Save response to a file (for binary downloads like PDFs, images, documents)
9442
- - \`--no-cache\` \u2014 Fetch action details fresh instead of from the local cache (execution itself is never cached)
9490
+ - \`--no-cache\` \u2014 Bypass the cached action details and re-fetch them; the fresh details still refresh the cache (execution itself is never cached)
9443
9491
 
9444
9492
  Execute reuses the action details cached by \`actions knowledge\` (method, path, schema), so in the standard search \u2192 knowledge \u2192 execute flow it makes a single API call \u2014 the action being executed. The live response is never cached. In \`--agent\` mode the response includes \`"_preflight": {"cache": "hit"|"miss"}\` showing whether the lookup was served from disk.
9445
9493
 
@@ -10566,20 +10614,20 @@ function buildWorkflowIdeas(connections) {
10566
10614
  // src/commands/logout.ts
10567
10615
  import fs12 from "fs";
10568
10616
  import * as p9 from "@clack/prompts";
10569
- function formatWhoami(config2, apiKey, pc13) {
10617
+ function formatWhoami(config2, apiKey, pc14) {
10570
10618
  const whoami = config2.whoami;
10571
10619
  const env = getEnvFromApiKey(apiKey);
10572
- const envLabel = env === "test" ? pc13.yellow("test") : pc13.green("live");
10620
+ const envLabel = env === "test" ? pc14.yellow("test") : pc14.green("live");
10573
10621
  const lines = [];
10574
10622
  if (whoami) {
10575
10623
  const contextParts = [];
10576
10624
  if (whoami.organization) contextParts.push(whoami.organization.name);
10577
10625
  if (whoami.project) contextParts.push(whoami.project.name);
10578
10626
  const scopeDisplay = contextParts.length > 0 ? contextParts.join(" / ") : "Personal";
10579
- lines.push(`${pc13.bold(scopeDisplay)} ${pc13.dim("\xB7")} ${envLabel}`);
10580
- 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})`)}`);
10581
10629
  } else {
10582
- 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}`);
10583
10631
  }
10584
10632
  return lines;
10585
10633
  }
@@ -10608,7 +10656,7 @@ async function logoutCommand() {
10608
10656
  json({ status: cleared ? "logged_out" : "not_logged_in", message: cleared ? "Credentials cleared." : "No config found." });
10609
10657
  return;
10610
10658
  }
10611
- const pc13 = (await import("picocolors")).default;
10659
+ const pc14 = (await import("picocolors")).default;
10612
10660
  const globalConfig = readGlobalConfig();
10613
10661
  const projectConfig = readProjectConfig();
10614
10662
  const hasGlobal = globalConfig?.apiKey != null;
@@ -10617,13 +10665,13 @@ async function logoutCommand() {
10617
10665
  if (hasGlobal && hasProject) {
10618
10666
  const infoLines = ["You are logged in with multiple configs.", ""];
10619
10667
  if (projectConfig) {
10620
- infoLines.push(`${pc13.cyan("Local config:")}`);
10621
- infoLines.push(...formatWhoami(projectConfig, projectConfig.apiKey, pc13));
10668
+ infoLines.push(`${pc14.cyan("Local config:")}`);
10669
+ infoLines.push(...formatWhoami(projectConfig, projectConfig.apiKey, pc14));
10622
10670
  infoLines.push("");
10623
10671
  }
10624
10672
  if (globalConfig) {
10625
- infoLines.push(`${pc13.magenta("Global config:")}`);
10626
- infoLines.push(...formatWhoami(globalConfig, globalConfig.apiKey, pc13));
10673
+ infoLines.push(`${pc14.magenta("Global config:")}`);
10674
+ infoLines.push(...formatWhoami(globalConfig, globalConfig.apiKey, pc14));
10627
10675
  }
10628
10676
  p9.note(infoLines.join("\n"));
10629
10677
  const choice = await p9.select({
@@ -10641,14 +10689,14 @@ async function logoutCommand() {
10641
10689
  targetScope = choice;
10642
10690
  } else if (hasProject) {
10643
10691
  const infoLines = ["You are logged in.", ""];
10644
- infoLines.push(`${pc13.dim("Stored in")} ${pc13.cyan("local config")}`);
10645
- 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));
10646
10694
  p9.note(infoLines.join("\n"));
10647
10695
  targetScope = "project";
10648
10696
  } else if (hasGlobal) {
10649
10697
  const infoLines = ["You are logged in.", ""];
10650
- infoLines.push(`${pc13.dim("Stored in")} ${pc13.magenta("global config")}`);
10651
- 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));
10652
10700
  p9.note(infoLines.join("\n"));
10653
10701
  targetScope = "global";
10654
10702
  } else {
@@ -10682,9 +10730,165 @@ async function logoutCommand() {
10682
10730
  p9.outro("Logged out.");
10683
10731
  }
10684
10732
 
10685
- // 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";
10686
10737
  var require3 = createRequire2(import.meta.url);
10687
- 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");
10688
10892
  var program = new Command();
10689
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.
10690
10894
 
@@ -10760,11 +10964,14 @@ program.name("one").option("--agent", "Machine-readable JSON output (no colors,
10760
10964
  Platform names are lowercase; multi-word names use dashes (e.g. hubspot, ship-station, google-calendar).
10761
10965
  Run 'one platforms' to browse all 400+ available platforms.`).version(version);
10762
10966
  var updateCheckPromise;
10763
- program.hook("preAction", (thisCommand) => {
10967
+ program.hook("preAction", (thisCommand, actionCommand) => {
10764
10968
  const opts = program.opts();
10765
10969
  if (opts.agent) {
10766
10970
  setAgentMode(true);
10767
10971
  }
10972
+ maybeShowTelemetryNotice();
10973
+ captureCommand(actionCommand);
10974
+ drainQueue();
10768
10975
  const commandName = thisCommand.args?.[0];
10769
10976
  if (commandName !== "update") {
10770
10977
  updateCheckPromise = checkLatestVersionCached();
@@ -10778,6 +10985,7 @@ program.hook("preAction", (thisCommand) => {
10778
10985
  });
10779
10986
  program.hook("postAction", async () => {
10780
10987
  await closeBackendIfCached();
10988
+ flush();
10781
10989
  if (!updateCheckPromise) return;
10782
10990
  const info = await updateCheckPromise;
10783
10991
  if (!info) return;
@@ -10961,13 +11169,13 @@ program.command("platforms").alias("p").description("List available platforms").
10961
11169
  await platformsCommand(options);
10962
11170
  });
10963
11171
  var actions = program.command("actions").alias("a").description("Search, explore, and execute platform actions (workflow: search \u2192 knowledge \u2192 execute)");
10964
- actions.command("search <platform> <query>").description('Search for actions on a platform (e.g. one actions search gmail "send email")').option("-t, --type <type>", "execute (to run it) or knowledge (to learn about it). Default: knowledge").option("--no-cache", "Skip cache, fetch fresh from API").action(async (platform, query, options) => {
11172
+ actions.command("search <platform> <query>").description('Search for actions on a platform (e.g. one actions search gmail "send email")').option("-t, --type <type>", "execute (to run it) or knowledge (to learn about it). Default: knowledge").option("--no-cache", "Bypass the cache and re-fetch from the API (the fresh response still refreshes the cache)").action(async (platform, query, options) => {
10965
11173
  await actionsSearchCommand(platform, query, options);
10966
11174
  });
10967
- actions.command("knowledge <platform> <actionId>").alias("k").description("Get full docs for an action \u2014 MUST call before execute to know required params").option("--no-cache", "Skip cache, fetch fresh from API").option("--cache-status", "Print cache metadata without fetching").action(async (platform, actionId, options) => {
11175
+ actions.command("knowledge <platform> <actionId>").alias("k").description("Get full docs for an action \u2014 MUST call before execute to know required params").option("--no-cache", "Bypass the cache and re-fetch from the API (the fresh response still refreshes the cache)").option("--cache-status", "Print cache metadata without fetching").action(async (platform, actionId, options) => {
10968
11176
  await actionsKnowledgeCommand(platform, actionId, options);
10969
11177
  });
10970
- actions.command("execute [platform] [actionId] [connectionKey]").alias("x").allowUnknownOption(true).allowExcessArguments(true).description("Execute an action (or multiple with --parallel, separated by --)").option("-d, --data <json>", "Request body as JSON").option("--path-vars <json>", "Path variables as JSON").option("--query-params <json>", "Query parameters as JSON").option("--headers <json>", "Additional headers as JSON").option("--form-data", "Send as multipart/form-data").option("--form-url-encoded", "Send as application/x-www-form-urlencoded").option("--dry-run", "Show request that would be sent without executing").option("--mock", "Return example response without making an API call").option("--skip-validation", "Skip input validation against the action schema").option("--no-cache", "Fetch action details fresh instead of using the local cache (execution itself is never cached)").option("--output <path>", "Save binary response to a file (for non-JSON responses like file downloads)").option("--parallel", "Execute multiple actions concurrently (separate actions with --)").option("--max-concurrency <n>", "Max concurrent actions when using --parallel (default: 5)", "5").action(async (platform, actionId, connectionKey, options) => {
11178
+ actions.command("execute [platform] [actionId] [connectionKey]").alias("x").allowUnknownOption(true).allowExcessArguments(true).description("Execute an action (or multiple with --parallel, separated by --)").option("-d, --data <json>", "Request body as JSON").option("--path-vars <json>", "Path variables as JSON").option("--query-params <json>", "Query parameters as JSON").option("--headers <json>", "Additional headers as JSON").option("--form-data", "Send as multipart/form-data").option("--form-url-encoded", "Send as application/x-www-form-urlencoded").option("--dry-run", "Show request that would be sent without executing").option("--mock", "Return example response without making an API call").option("--skip-validation", "Skip input validation against the action schema").option("--no-cache", "Bypass the cached action details and re-fetch them (the fresh details still refresh the cache; execution itself is never cached)").option("--output <path>", "Save binary response to a file (for non-JSON responses like file downloads)").option("--parallel", "Execute multiple actions concurrently (separate actions with --)").option("--max-concurrency <n>", "Max concurrent actions when using --parallel (default: 5)", "5").action(async (platform, actionId, connectionKey, options) => {
10971
11179
  if (options.parallel) {
10972
11180
  await actionsExecuteParallelCommand();
10973
11181
  return;
@@ -11096,21 +11304,21 @@ program.command("whoami").description("Show the user, organization, and project
11096
11304
  });
11097
11305
  return;
11098
11306
  }
11099
- const pc13 = (await import("picocolors")).default;
11307
+ const pc14 = (await import("picocolors")).default;
11100
11308
  const contextParts = [];
11101
11309
  if (whoami.organization) contextParts.push(whoami.organization.name);
11102
11310
  if (whoami.project) contextParts.push(whoami.project.name);
11103
11311
  const scopeDisplay = contextParts.length > 0 ? contextParts.join(" / ") : "Personal";
11104
- const envLabel = env === "test" ? pc13.yellow("test") : pc13.green("live");
11105
- 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");
11106
11314
  console.log();
11107
- console.log(` ${pc13.bold(scopeDisplay)} ${pc13.dim("\xB7")} ${envLabel}`);
11108
- console.log(` ${whoami.user.name} ${pc13.dim(`(${whoami.user.email})`)}`);
11109
- if (whoami.organization) console.log(` ${pc13.dim("Org:")} ${whoami.organization.name} ${pc13.dim(`(${whoami.organization.id})`)}`);
11110
- 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})`)}`);
11111
11319
  console.log();
11112
- console.log(` ${pc13.dim("Using")} ${configLabel}`);
11113
- console.log(` ${pc13.dim("API:")} ${apiBase}`);
11320
+ console.log(` ${pc14.dim("Using")} ${configLabel}`);
11321
+ console.log(` ${pc14.dim("API:")} ${apiBase}`);
11114
11322
  console.log();
11115
11323
  });
11116
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.0",
3
+ "version": "1.46.0",
4
4
  "description": "CLI for managing One",
5
5
  "type": "module",
6
6
  "files": [
@@ -90,7 +90,7 @@ Options:
90
90
  - `--mock` — Return example response without making an API call (useful for building UI)
91
91
  - `--skip-validation` — Skip input validation against the action schema
92
92
  - `--output <path>` — Save response to a file (for binary downloads like PDFs, images, documents)
93
- - `--no-cache` — Fetch action details fresh instead of from the local cache (execution itself is never cached)
93
+ - `--no-cache` — Bypass the cached action details and re-fetch them; the fresh details still refresh the cache (execution itself is never cached)
94
94
 
95
95
  The CLI validates required parameters before executing. Missing params return a structured error with the flag name, parameter name, and description. Pass `--skip-validation` to bypass.
96
96
 
@@ -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
- };