@withone/cli 1.53.0 → 1.54.1

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
@@ -24,7 +24,7 @@
24
24
  <a href="https://withone.ai/knowledge"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fapi.withone.ai%2Fopen%2Fcount%2Ftools" alt="tools"></a>
25
25
  </p>
26
26
 
27
- One gives your AI agent authenticated access to 400+ platforms - Gmail, Slack, Shopify, HubSpot, Stripe, Notion, and everything else - through a single interface. No API keys to juggle, no OAuth flows to build, no request formats to memorize. Connect a platform once, and your agent can search for actions, read the docs, and execute API calls in seconds.
27
+ One gives your AI agent authenticated access to 600+ platforms - Gmail, Slack, Shopify, HubSpot, Stripe, Notion, and everything else - through a single interface. No API keys to juggle, no OAuth flows to build, no request formats to memorize. Connect a platform once, and your agent can search for actions, read the docs, and execute API calls in seconds.
28
28
 
29
29
  ## Install
30
30
 
@@ -48,7 +48,10 @@ one login # Opens browser for authentication (global or per-directo
48
48
  one logout # Clear credentials (with scope picker and confirmation)
49
49
  ```
50
50
 
51
- Requires Node.js 18+.
51
+ Requires Node.js 18+. `one sync` additionally needs Node 20+, because its
52
+ local SQLite engine (`better-sqlite3`, an optional dependency) ships prebuilt
53
+ binaries only for Node 20 and above. On Node 18 every other command works
54
+ normally; `one sync` reports that the engine isn't installed.
52
55
 
53
56
  ## Quick start
54
57
 
@@ -241,7 +244,7 @@ Shows the connection details and asks for confirmation before deleting. Use `--f
241
244
 
242
245
  ### `one platforms`
243
246
 
244
- Browse all 200+ available platforms.
247
+ Browse all 600+ available platforms.
245
248
 
246
249
  ```bash
247
250
  one platforms # all platforms
@@ -143,6 +143,15 @@ function loadBuiltinProfile(platform, model) {
143
143
  return null;
144
144
  }
145
145
  }
146
+ var CAPABILITY_FIELDS = ["identityKeys", "identityKey", "enrich", "dateFilter", "memory"];
147
+ function findMissingBuiltinCapabilities(platform, model, installed) {
148
+ if (!installed) return [];
149
+ const builtin = loadBuiltinProfile(platform, model);
150
+ if (!builtin) return [];
151
+ return CAPABILITY_FIELDS.filter(
152
+ (field) => builtin[field] !== void 0 && installed[field] === void 0
153
+ );
154
+ }
146
155
  function listBuiltinProfiles(platform) {
147
156
  const dir = getProfilesDir();
148
157
  if (!dir) return [];
@@ -1070,6 +1079,7 @@ export {
1070
1079
  resolveEntityIdentity,
1071
1080
  collectIdentityKeys,
1072
1081
  loadBuiltinProfile,
1082
+ findMissingBuiltinCapabilities,
1073
1083
  listBuiltinProfiles,
1074
1084
  memMigrateCommand,
1075
1085
  buildIdentityMap,
package/dist/index.js CHANGED
@@ -45,6 +45,7 @@ import {
45
45
  ensureTable,
46
46
  evolveSchema,
47
47
  extractSearchableFromPaths,
48
+ findMissingBuiltinCapabilities,
48
49
  generateTemplate,
49
50
  getDatabaseSize,
50
51
  getSearchablePaths,
@@ -65,7 +66,7 @@ import {
65
66
  writeDraftProfile,
66
67
  writePageToMemory,
67
68
  writeProfile
68
- } from "./chunk-IKYXS7EI.js";
69
+ } from "./chunk-XN4ZWMLX.js";
69
70
  import {
70
71
  getByDotPath
71
72
  } from "./chunk-44CV5IMX.js";
@@ -1103,7 +1104,7 @@ async function loginCommand() {
1103
1104
  console.log(pc15.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"));
1104
1105
  console.log(pc15.cyan(" \u2502"));
1105
1106
  console.log(pc15.cyan(" \u2502 The One CLI (`one`) is now installed on this machine. It"));
1106
- console.log(pc15.cyan(" \u2502 lets you interact with 400+ third-party platforms (Gmail,"));
1107
+ console.log(pc15.cyan(" \u2502 lets you interact with 600+ third-party platforms (Gmail,"));
1107
1108
  console.log(pc15.cyan(" \u2502 Slack, Shopify, HubSpot, Stripe, GitHub, etc.) through"));
1108
1109
  console.log(pc15.cyan(" \u2502 their APIs. Whenever you need to interact with any"));
1109
1110
  console.log(pc15.cyan(" \u2502 third-party platform or external service, use the `one`"));
@@ -1710,7 +1711,7 @@ function printOnboardingPrompt() {
1710
1711
  console.log(pc2.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"));
1711
1712
  console.log(pc2.cyan(" \u2502"));
1712
1713
  console.log(pc2.cyan(" \u2502 The One CLI (`one`) is now installed on this machine. It"));
1713
- console.log(pc2.cyan(" \u2502 lets you interact with 400+ third-party platforms (Gmail,"));
1714
+ console.log(pc2.cyan(" \u2502 lets you interact with 600+ third-party platforms (Gmail,"));
1714
1715
  console.log(pc2.cyan(" \u2502 Slack, Shopify, HubSpot, Stripe, GitHub, etc.) through"));
1715
1716
  console.log(pc2.cyan(" \u2502 their APIs. Whenever you need to interact with any"));
1716
1717
  console.log(pc2.cyan(" \u2502 third-party platform or external service, use the `one`"));
@@ -1887,7 +1888,7 @@ async function promptConnectIntegrations(apiKey, connParams) {
1887
1888
  label: i.label,
1888
1889
  hint: i.hint
1889
1890
  })),
1890
- { value: "more", label: "Browse all 200+ platforms" },
1891
+ { value: "more", label: "Browse all 600+ platforms" },
1891
1892
  { value: "skip", label: "Skip for now", hint: "you can always run one add later" }
1892
1893
  ];
1893
1894
  const message = first ? "Connect your first integration?" : "Connect another?";
@@ -7829,7 +7830,12 @@ async function syncProfilesCommand(platform) {
7829
7830
  model: p10.model,
7830
7831
  description: p10.description,
7831
7832
  hasEnrich: !!p10.enrich,
7832
- hasIdentityKey: !!p10.identityKey
7833
+ // `identityKey` (singular) is the entity-merge key; `identityKeys`
7834
+ // (plural, #167) are non-merging association keys. Reading only the
7835
+ // singular reported hasIdentityKey:false for gmail/gcal/fathom — the
7836
+ // three profiles the plural form was added for. (#129/#130)
7837
+ hasIdentityKey: !!p10.identityKey || !!p10.identityKeys,
7838
+ hasIdentityKeys: !!p10.identityKeys
7833
7839
  })),
7834
7840
  total: profiles.length,
7835
7841
  _hint: profiles.length > 0 ? "Use a built-in profile: one --agent sync init <platform> <model>" : "No built-in profiles found. Use sync init to auto-infer from action knowledge."
@@ -7846,7 +7852,7 @@ async function syncProfilesCommand(platform) {
7846
7852
  for (const p10 of profiles) {
7847
7853
  const extras = [];
7848
7854
  if (p10.enrich) extras.push("enrich");
7849
- if (p10.identityKey) extras.push("identity");
7855
+ if (p10.identityKey || p10.identityKeys) extras.push("identity");
7850
7856
  if (p10.dateFilter) extras.push("incremental");
7851
7857
  const tags = extras.length > 0 ? ` ${pc9.dim(`[${extras.join(", ")}]`)}` : "";
7852
7858
  console.log(` ${pc9.bold(`${p10.platform}/${p10.model}`.padEnd(35))} ${p10.description}${tags}`);
@@ -8158,6 +8164,15 @@ async function syncRunCommand(platform, options) {
8158
8164
  if (!options.dryRun) {
8159
8165
  await maybeAutoMigrateLegacy(platform, toSync.map((p10) => p10.model));
8160
8166
  }
8167
+ const profileDrift = toSync.map((p10) => ({ model: p10.model, missing: findMissingBuiltinCapabilities(platform, p10.model, p10) })).filter((d) => d.missing.length > 0);
8168
+ if (profileDrift.length > 0 && !isAgentMode()) {
8169
+ for (const d of profileDrift) {
8170
+ console.log(
8171
+ ` ${pc9.yellow("!")} ${platform}/${d.model} is missing ${d.missing.map((f) => pc9.bold(f)).join(", ")} from the current built-in profile.
8172
+ Run ${pc9.bold(`one sync init ${platform} ${d.model}`)} to pick ${d.missing.length > 1 ? "them" : "it"} up.`
8173
+ );
8174
+ }
8175
+ }
8161
8176
  const results = [];
8162
8177
  for (const profile of toSync) {
8163
8178
  try {
@@ -8181,7 +8196,19 @@ async function syncRunCommand(platform, options) {
8181
8196
  }
8182
8197
  }
8183
8198
  if (isAgentMode()) {
8184
- json({ platform, results });
8199
+ json({
8200
+ platform,
8201
+ results,
8202
+ // Surfaced to agents too: a profile silently missing a capability the
8203
+ // built-in now declares is invisible in the record counts. (#129/#130)
8204
+ ...profileDrift.length > 0 ? {
8205
+ profileDrift: profileDrift.map((d) => ({
8206
+ model: d.model,
8207
+ missingFields: d.missing,
8208
+ fix: `one sync init ${platform} ${d.model}`
8209
+ }))
8210
+ } : {}
8211
+ });
8185
8212
  return;
8186
8213
  }
8187
8214
  for (const r of results) {
@@ -8352,7 +8379,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
8352
8379
  ` detected legacy .one/sync/data/${platform}.db (${dbSize}) \u2014 auto-migrating into memory before sync.
8353
8380
  `
8354
8381
  );
8355
- const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-U2MZVGU6.js");
8382
+ const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-UGDDHWGY.js");
8356
8383
  await memMigrateCommand3({ platform, yes: true });
8357
8384
  return;
8358
8385
  }
@@ -8361,7 +8388,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
8361
8388
  initialValue: true
8362
8389
  });
8363
8390
  if (p7.isCancel(shouldMigrate) || !shouldMigrate) return;
8364
- const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-U2MZVGU6.js");
8391
+ const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-UGDDHWGY.js");
8365
8392
  await memMigrateCommand2({ platform, yes: true });
8366
8393
  }
8367
8394
  async function syncSuggestSearchableCommand(platformModel, options = {}) {
@@ -10009,7 +10036,7 @@ Before using any feature, read its guide section first: \`one guide actions\`, \
10009
10036
 
10010
10037
  ## Features
10011
10038
 
10012
- ### 1. Actions \u2014 Execute API calls on 400+ platforms
10039
+ ### 1. Actions \u2014 Execute API calls on 600+ platforms
10013
10040
  Search for actions, read their docs, and execute them. This is the core workflow.
10014
10041
 
10015
10042
  **Quick start:**
@@ -10908,6 +10935,10 @@ Two ways to tag a record with a cross-platform identifier (e.g. email), dependin
10908
10935
 
10909
10936
  Each \`path\` supports \`[]\` wildcards (one key per element) and a \`[name=From]\` equality filter (e.g. Gmail \`messages[].payload.headers[name=From].value\`). \`email\`-prefixed values are email-extracted, so display-name headers (\`"Jane <jane@acme.com>"\`) and comma-lists normalize cleanly. Values are lowercased/trimmed/deduped. \`sync test\` previews how many identity keys each record resolves.
10910
10937
 
10938
+ The built-in \`gmail/gmailThreads\` profile collects From/To/**Cc/Bcc**. Gmail only returns a \`Bcc\` header on messages the authenticated user sent \u2014 it is stripped for recipients \u2014 so Bcc keys appear on your own sent threads and nowhere else.
10939
+
10940
+ **Upgrading an existing profile.** \`sync run\` reads only your on-disk profile at \`.one/sync/profiles/<platform>_<model>.json\` \u2014 it never merges built-in updates, so a profile created before a capability shipped will not have it. \`sync run\` now warns when the shipped built-in declares \`identityKeys\`, \`identityKey\`, \`enrich\`, \`dateFilter\`, or \`memory\` that your copy lacks, and \`--agent\` output carries a \`profileDrift\` array with the same information. Run \`one sync init <platform> <model>\` to pick the fields up (it patches, preserving your edits).
10941
+
10911
10942
  Query everything sharing an identity key, grouped by type:
10912
10943
 
10913
10944
  \`\`\`bash
@@ -11198,7 +11229,7 @@ function buildStep1() {
11198
11229
  nextCommand: "one onboard --step 2",
11199
11230
  message: `# One CLI \u2014 Agent Onboarding
11200
11231
 
11201
- You now have access to the One CLI. It connects you to 400+ platforms
11232
+ You now have access to the One CLI. It connects you to 600+ platforms
11202
11233
  (Gmail, Slack, Stripe, Notion, etc.) \u2014 you'll learn the details shortly.
11203
11234
 
11204
11235
  IMPORTANT: Your only task right now is to send the message below to the
@@ -11208,7 +11239,7 @@ Do not offer demos yet. Just send this message and wait for their reply:
11208
11239
  ---
11209
11240
 
11210
11241
  I just got access to the One CLI \u2014 it connects me to your platforms like
11211
- Gmail, Slack, Stripe, and 400+ others so I can work with them directly.
11242
+ Gmail, Slack, Stripe, and 600+ others so I can work with them directly.
11212
11243
  I'll show you what I can do in a moment.
11213
11244
 
11214
11245
  First, one quick setup step: right now only this conversation knows about
@@ -11237,7 +11268,7 @@ If they declined, skip this section.
11237
11268
  ## One CLI \u2014 Platform Integrations
11238
11269
 
11239
11270
  The One CLI (\`one\`) is installed and configured on this machine. It is a
11240
- command-line tool that gives AI agents the ability to interact with 400+
11271
+ command-line tool that gives AI agents the ability to interact with 600+
11241
11272
  third-party platforms (Gmail, Slack, Shopify, HubSpot, Stripe, GitHub,
11242
11273
  Notion, Salesforce, etc.) through a single, unified interface.
11243
11274
 
@@ -11332,7 +11363,7 @@ function buildStep3(connections) {
11332
11363
  The user can connect any of these popular platforms:
11333
11364
  Gmail, Google Calendar, Slack, Notion, Shopify, Stripe, HubSpot, GitHub,
11334
11365
  Salesforce, QuickBooks, Asana, Jira, Linear, Intercom, Zendesk, Twilio,
11335
- and 400+ more. Run \`one platforms\` for the full list.`);
11366
+ and 600+ more. Run \`one platforms\` for the full list.`);
11336
11367
  sections.push("## Onboarding complete!\n\nYou're all set. Use `one --agent guide` any time you need the full reference.");
11337
11368
  return {
11338
11369
  step: 3,
@@ -11363,7 +11394,7 @@ platform before you can start using actions. Suggest they run:
11363
11394
  one add slack
11364
11395
  one add <any-platform>
11365
11396
 
11366
- Run \`one platforms\` to see all 400+ available platforms.`;
11397
+ Run \`one platforms\` to see all 600+ available platforms.`;
11367
11398
  }
11368
11399
  const header = `## Current State
11369
11400
 
@@ -11800,7 +11831,7 @@ silenceWarningsInAgentMode();
11800
11831
  var require4 = createRequire3(import.meta.url);
11801
11832
  var { version } = require4("../package.json");
11802
11833
  var program = new Command();
11803
- 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.
11834
+ program.name("one").option("--agent", "Machine-readable JSON output (no colors, spinners, or prompts)").description(`One CLI \u2014 Connect AI agents to 600+ platforms through one interface.
11804
11835
 
11805
11836
  Setup:
11806
11837
  one login Authenticate via browser (opens app.withone.ai)
@@ -11872,7 +11903,7 @@ program.name("one").option("--agent", "Machine-readable JSON output (no colors,
11872
11903
  -d '{"to":"j@example.com","subject":"Hello","body":"Hi!","connectionKey":"live::gmail::default::abc123"}'
11873
11904
 
11874
11905
  Platform names are lowercase; multi-word names use dashes (e.g. hubspot, ship-station, google-calendar).
11875
- Run 'one platforms' to browse all 400+ available platforms.`).version(version);
11906
+ Run 'one platforms' to browse all 600+ available platforms.`).version(version);
11876
11907
  var updateCheckPromise;
11877
11908
  program.hook("preAction", (thisCommand, actionCommand) => {
11878
11909
  const opts = program.opts();
@@ -3,7 +3,7 @@ import {
3
3
  dotPathToJsonbExpr,
4
4
  memMigrateCommand,
5
5
  reviveStringifiedJson
6
- } from "./chunk-IKYXS7EI.js";
6
+ } from "./chunk-XN4ZWMLX.js";
7
7
  import "./chunk-44CV5IMX.js";
8
8
  import "./chunk-GNSR3NYN.js";
9
9
  import "./chunk-DDCDPVJH.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withone/cli",
3
- "version": "1.53.0",
3
+ "version": "1.54.1",
4
4
  "description": "CLI for managing One",
5
5
  "type": "module",
6
6
  "files": [
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "optionalDependencies": {
38
38
  "@electric-sql/pglite": "^0.2.17",
39
- "better-sqlite3": "^11.7.0",
39
+ "better-sqlite3": "^12.11.1",
40
40
  "pg": "^8.20.0"
41
41
  },
42
42
  "devDependencies": {
@@ -18,7 +18,8 @@
18
18
  "identityKeys": [
19
19
  { "prefix": "email", "path": "messages[].payload.headers[name=From].value" },
20
20
  { "prefix": "email", "path": "messages[].payload.headers[name=To].value" },
21
- { "prefix": "email", "path": "messages[].payload.headers[name=Cc].value" }
21
+ { "prefix": "email", "path": "messages[].payload.headers[name=Cc].value" },
22
+ { "prefix": "email", "path": "messages[].payload.headers[name=Bcc].value" }
22
23
  ],
23
24
  "enrich": {
24
25
  "actionId": "conn_mod_def::GJ3ok0Eq0R8::AAzgZVLqTg2iBuITKpJLZg",
@@ -20,7 +20,7 @@ description: |
20
20
 
21
21
  # One CLI
22
22
 
23
- You have access to the One CLI which lets you interact with 400+ third-party platforms through their APIs. Always include the `--agent` flag right after `one` for structured JSON output.
23
+ You have access to the One CLI which lets you interact with 600+ third-party platforms through their APIs. Always include the `--agent` flag right after `one` for structured JSON output.
24
24
 
25
25
  If the user wants a separate API key / connections for a specific project (vs. their default), walk them through running `one init` from that project folder and picking the "project" scope — see `references/scoping.md`. For monorepo subprojects (where a parent already has `.git`/`package.json`), have them `mkdir .one` in the subproject first so the config is keyed to that dir, not the monorepo root.
26
26
 
@@ -311,6 +311,8 @@ Without declared paths, the default walker concatenates every string in the reco
311
311
 
312
312
  **Connections are late-bound** — profiles use `"connection": { "platform": "<name>" }`, not literal `connectionKey` strings. The key is resolved at sync time, so `one add <platform>` (re-auth) doesn't break the profile. For multi-account platforms, add `"tag": "<connection-tag>"` to disambiguate, and create the tagged connection with `one add <platform> --tag <name>`. Don't hardcode connection keys in profiles.
313
313
 
314
+ **Installed profiles do not auto-update.** `sync run` reads only `.one/sync/profiles/<platform>_<model>.json` and never merges the shipped built-in, so a profile created before a capability shipped silently lacks it — a pre-#167 gmail profile writes zero identity keys, forever, with no change in record counts. `sync run` warns when the built-in declares `identityKeys` / `identityKey` / `enrich` / `dateFilter` / `memory` that your copy lacks (agent mode: a `profileDrift` array). Fix with `one sync init <platform> <model>`, which patches rather than overwrites.
315
+
314
316
  **Cross-platform identity on a profile.** Two separate fields, and picking the wrong one silently mangles data:
315
317
 
316
318
  - `"identityKey": "properties.email"` — singular. "This record IS this entity." One dot-path; the value lands in `keys[]` and MERGES records for the same entity across platforms (HubSpot + Attio for one person collapse into a single record).