@withone/cli 1.57.1 → 2.1.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
@@ -64,18 +64,15 @@ one add gmail
64
64
  # See what you're connected to
65
65
  one list
66
66
 
67
- # Search for actions you can take
68
- one actions search gmail "send email" -t execute
69
-
70
- # Read the docs for an action
71
- one actions knowledge gmail <actionId>
67
+ # Find the action, with its docs
68
+ one actions find gmail "send an email" --task "email a hello to a contact"
72
69
 
73
70
  # Execute it
74
71
  one actions execute gmail <actionId> <connectionKey> \
75
72
  -d '{"to": "jane@example.com", "subject": "Hello", "body": "Sent from my AI agent"}'
76
73
  ```
77
74
 
78
- That's it. Five commands to go from zero to sending an email through Gmail's API - fully authenticated, correctly formatted, without touching a single OAuth token.
75
+ That's it. Four commands to go from zero to sending an email through Gmail's API - fully authenticated, correctly formatted, without touching a single OAuth token.
79
76
 
80
77
  ### Multi-step flows
81
78
 
@@ -210,7 +207,7 @@ You need the connection key (rightmost column) when executing actions.
210
207
  | `{"policy": "methods", "methods": ["GET"]}` | Only actions with those HTTP methods | Permission level is `read` or `write` |
211
208
  | `{"policy": "actions", "actions": [{"actionId": "...", "title": "...", "method": "..."}]}` | Only these specific actions | An action allowlist is configured |
212
209
 
213
- An action allowlist wins over the permission level (and is then method-filtered by it). When the policy is `actions`, those actions are exactly what may run — no `actions search` needed.
210
+ An action allowlist wins over the permission level (and is then method-filtered by it). When the policy is `actions`, those actions are exactly what may run — `actions load <actionId>` reads their docs, no find needed.
214
211
 
215
212
  ```jsonc
216
213
  // one --agent list
@@ -258,39 +255,38 @@ one platforms -c "CRM" # filter by category
258
255
  one platforms --json # machine-readable output
259
256
  ```
260
257
 
261
- ### `one actions search <platform> <query>`
258
+ ### `one actions find <platform> <intent> [<platform> <intent> ...]`
262
259
 
263
- Search for API actions on a connected platform using natural language.
260
+ Find the action for every operation a task needs, across platforms, **with its documentation**, in one call: parameters, validation rules, request/response structure, and platform-specific quirks. One's decision model picks the action for each intent.
264
261
 
265
262
  ```bash
266
- one actions search shopify "list products"
267
- one actions search hubspot "create contact" -t execute
268
- one actions search gmail "send email"
263
+ one actions find gmail "send an email"
264
+ one actions find hubspot "find a contact by email" gmail "send an email" --task "email a follow-up to a CRM contact"
265
+ one actions find shopify "list products" -t knowledge
269
266
  ```
270
267
 
271
- Returns the top 5 matching actions with their action IDs, HTTP methods, and paths. Use `-t execute` when you intend to run the action, or `-t knowledge` (default) when you want to learn about it or write code against it.
272
-
273
- ### `one actions knowledge <platform> <actionId>`
268
+ - Each **intent** names the operation alone, in a few words (`"send a message to a channel"`), without its data: IDs, names and message text make the search miss. Up to 10 pairs.
269
+ - **`--task`** describes the whole job in one line, in general terms, which helps choose between similar actions.
270
+ - **`-t knowledge`** searches the catalog for writing code and building flows and relays, which includes the platform's own (passthrough) endpoints; the default is the catalog for running actions now.
271
+ - **`--ai-model`** names the model running the CLI (e.g. `claude-sonnet-5`), for tuning documentation per model later.
272
+ - **`--no-knowledge`** lists the chosen actions (actionId, title, method, path) without fetching their documentation; load it later with `one actions load <actionId>`.
274
273
 
275
- Get the full documentation for an action - parameters, validation rules, request/response structure, examples, and the exact API request format.
274
+ Each intent's answer gives the action(s) to use with their docs, any actions also needed beside them, a **substitute** when the model was unsure (use one or the other, never both), and a few alternatives, then says once how to execute. Always read the docs before executing. The access settings from `one config` apply: an action they refuse is never offered.
276
275
 
277
- ```bash
278
- one actions knowledge shopify 67890abcdef
279
- ```
276
+ Large documents come back as a **digest**: request-building sections in full (method/URL, headers, description, enforcement rules, required and optional parameters, sample request, gotchas, error handling), then a notice naming what was left out with the exact command to load it. In knowledge-only mode each pick comes back whole, with how to call it from code.
280
277
 
281
- Always read the knowledge before executing. It tells you exactly what parameters are required, what format they need, and any platform-specific quirks.
278
+ ### `one actions load <actionId...>`
282
279
 
283
- In `--agent` mode the response is a **digest**: request-building sections in full (method/URL, headers, description, enforcement rules, required and optional parameters, sample request, gotchas, error handling) plus a table of contents for the rest. Response shapes, response-field tables, and worked examples — the bulk of every large doc — are loaded on demand:
280
+ More of an action's documentation: the digest by default (how to read an alternative from a find answer), or a section a digest left out, the whole document, or its table of contents. Up to 10 action ids.
284
281
 
285
282
  ```bash
286
- one --agent actions knowledge github <actionId> # digest + sections[] table of contents
287
- one --agent actions knowledge github <actionId> --section "Response Fields" # one section, by heading or id
288
- one --agent actions knowledge github <actionId> --section response,examples # several, by alias
289
- one --agent actions knowledge github <actionId> --full # whole document
290
- one --agent actions knowledge github <actionId> --toc # every section id, no document
283
+ one --agent actions load <actionId> --section "Response Fields" # one section, by heading or id
284
+ one --agent actions load <actionId> --section response,examples # several, by alias
285
+ one --agent actions load <actionId> --full # whole document
286
+ one --agent actions load <actionId> --toc # every section id, no document
291
287
  ```
292
288
 
293
- The JSON carries `truncated`, `sections[]` (the omitted sections: id, heading, chars), and `more` (the commands to load the rest); the markdown ends with the same notice so it is never mistaken for the complete doc. Small documents are returned whole. Section requests are served from the local cache. Human (non-agent) output always prints the full document; `--section` works there too.
289
+ Loads are served from the local cache once a doc is cached.
294
290
 
295
291
  ### `one actions execute <platform> <actionId> <connectionKey>`
296
292
 
@@ -351,7 +347,7 @@ Agent-mode output includes `parallel: true`, per-action `status`/`durationMs`/`r
351
347
 
352
348
  ### `one cache`
353
349
 
354
- Manage the local cache for knowledge and search responses. The CLI automatically caches `actions knowledge` and `actions search` results so repeated calls serve instantly from disk. `actions execute` reuses the cached action details (method, path, validation schema) for its preflight lookup, so a knowledge call followed by execute costs a single API round trip.
350
+ Manage the local cache of action documentation. `actions find` and `actions load` read each action's details (docs, method, path, validation schema) through the cache, so repeated reads serve instantly from disk, and `actions execute` reuses them for its preflight lookup, so a find followed by execute costs a single API round trip for the execute.
355
351
 
356
352
  ```bash
357
353
  one cache list # List all cached entries with age and status
@@ -361,13 +357,13 @@ one cache clear <actionId> # Clear a specific entry
361
357
  one cache update-all # Re-fetch fresh data for all cached entries
362
358
  ```
363
359
 
364
- Knowledge and search commands also support cache flags:
360
+ Find, load and execute also support cache flags:
365
361
 
366
362
  ```bash
367
- one actions knowledge gmail <actionId> --no-cache # Skip cache, fetch fresh
368
- one actions knowledge gmail <actionId> --cache-status # Check cache status
369
- one actions knowledge gmail <actionId> --section response # Served from the cached doc, no fetch
370
- one actions search gmail "send email" --no-cache # Skip cache for search
363
+ one actions find gmail "send an email" --no-cache # Fetch the docs fresh
364
+ one actions load <actionId> --no-cache # Skip cache, fetch fresh
365
+ one actions load <actionId> --cache-status # Check cache status
366
+ one actions load <actionId> --section response # Served from the cached doc, no fetch
371
367
  one actions execute gmail <actionId> <key> --no-cache # Fresh action-details lookup
372
368
  ```
373
369
 
@@ -739,8 +735,7 @@ The power of One is in the workflow. Every interaction follows the same pattern:
739
735
 
740
736
  ```
741
737
  one list → What am I connected to?
742
- one actions search → What can I do?
743
- one actions knowledge → How do I do it?
738
+ one actions find → What do I run, and how?
744
739
  one actions execute → Do it.
745
740
  ```
746
741
 
@@ -749,7 +744,7 @@ This is the same workflow whether you're sending emails, creating CRM contacts,
749
744
  For multi-step workflows that chain actions across platforms:
750
745
 
751
746
  ```
752
- one actions knowledge → Learn each action's schema
747
+ one actions find → Find each action, with its schema
753
748
  one flow create → Define the workflow as JSON
754
749
  one flow validate → Check it
755
750
  one flow execute → Run it
@@ -766,11 +761,10 @@ If you're an AI agent using the One MCP server, the tools map directly:
766
761
  | MCP Tool | CLI Command |
767
762
  |----------|------------|
768
763
  | `list_one_integrations` | `one list` + `one platforms` |
769
- | `search_one_platform_actions` | `one actions search` |
770
- | `get_one_action_knowledge` | `one actions knowledge` |
764
+ | `find_one_actions` | `one actions find` (and `one actions load` for its `load`) |
771
765
  | `execute_one_action` | `one actions execute` |
772
766
 
773
- The workflow is the same: list → search → knowledge → execute. Never skip the knowledge step - it contains required parameter info and platform-specific details that are critical for building correct requests.
767
+ The workflow is the same: list → find → execute. Never execute without reading the docs find returns - they contain required parameter info and platform-specific details that are critical for building correct requests.
774
768
 
775
769
  ## MCP server installation
776
770
 
@@ -211,6 +211,19 @@ var OneApi = class {
211
211
  });
212
212
  return response || [];
213
213
  }
214
+ /**
215
+ * The action for each intent, across platforms, in one call: search plus
216
+ * One's decision model, which picks among the candidates. Core caps a call
217
+ * at 10 intents and refuses more with a 400 naming the cap.
218
+ */
219
+ async findActions(requests, task, knowledgeAgent) {
220
+ const response = await this.requestFull({
221
+ path: "/available-actions/find",
222
+ method: "POST",
223
+ body: { requests, ...task ? { task } : {}, knowledgeAgent }
224
+ });
225
+ return Array.isArray(response) ? response : [];
226
+ }
214
227
  async getActionDetails(actionId) {
215
228
  const response = await this.requestFull({
216
229
  path: "/knowledge",
@@ -222,19 +235,6 @@ var OneApi = class {
222
235
  }
223
236
  return actions[0];
224
237
  }
225
- async getActionKnowledge(actionId) {
226
- const action = await this.getActionDetails(actionId);
227
- if (!action.knowledge || !action.method) {
228
- return {
229
- knowledge: "No knowledge was found",
230
- method: "No method was found"
231
- };
232
- }
233
- return {
234
- knowledge: action.knowledge,
235
- method: action.method
236
- };
237
- }
238
238
  async requestWithMeta(opts) {
239
239
  let url = `${this.apiBase}${opts.path}`;
240
240
  if (opts.queryParams && Object.keys(opts.queryParams).length > 0) {
@@ -290,27 +290,6 @@ var OneApi = class {
290
290
  }
291
291
  return { data: actions[0], etag: result.etag, status: result.status };
292
292
  }
293
- async searchActionsWithMeta(platform, query, agentType, ifNoneMatch) {
294
- const isKnowledgeAgent = agentType === "knowledge";
295
- const queryParams = {
296
- query,
297
- limit: "5"
298
- };
299
- if (isKnowledgeAgent) {
300
- queryParams.knowledgeAgent = "true";
301
- } else {
302
- queryParams.executeAgent = "true";
303
- }
304
- const result = await this.requestWithMeta({
305
- path: `/available-actions/search/${platform}`,
306
- queryParams,
307
- ifNoneMatch
308
- });
309
- if (result.status === 304) {
310
- return { data: null, etag: result.etag, status: 304 };
311
- }
312
- return { data: result.data || [], etag: result.etag, status: result.status };
313
- }
314
293
  async executePassthroughRequest(args, preloadedAction) {
315
294
  const action = preloadedAction ?? await this.getActionDetails(args.actionId);
316
295
  const method = action.method;
@@ -555,11 +534,6 @@ var PERMISSION_METHODS = {
555
534
  write: ["GET", "POST", "PUT", "PATCH"],
556
535
  admin: null
557
536
  };
558
- function filterByPermissions(actions, permissions) {
559
- const allowed = PERMISSION_METHODS[permissions];
560
- if (allowed === null) return actions;
561
- return actions.filter((a) => allowed.includes(a.method.toUpperCase()));
562
- }
563
537
  function isMethodAllowed(method, permissions) {
564
538
  const allowed = PERMISSION_METHODS[permissions];
565
539
  if (allowed === null) return true;
@@ -568,32 +542,6 @@ function isMethodAllowed(method, permissions) {
568
542
  function isActionAllowed(actionId, allowedActionIds) {
569
543
  return allowedActionIds.includes("*") || allowedActionIds.includes(actionId);
570
544
  }
571
- function buildActionKnowledgeWithGuidance(knowledge, method, platform, actionId) {
572
- return `CLI EXECUTION GUIDE (read this FIRST)
573
- ========================================
574
- To execute this action, use the One CLI with SEPARATE flags for each parameter type.
575
- Do NOT pass path variables or query parameters in the -d body flag \u2014 this causes 403 errors.
576
-
577
- PARAMETER \u2192 FLAG MAPPING:
578
- - Path variables (URL placeholders like {userId}, {id}) \u2192 --path-vars '{"userId": "me"}'
579
- - Query parameters (filtering, pagination, format) \u2192 --query-params '{"key": "value"}'
580
- - For repeated params, use arrays: --query-params '{"metadataHeaders": ["From", "Subject"]}'
581
- - Request body (POST/PUT/PATCH payload) \u2192 -d '{"field": "value"}'
582
-
583
- EXAMPLE:
584
- one --agent actions execute ${platform} ${actionId} <connectionKey> \\
585
- --path-vars '{ ... }' \\
586
- --query-params '{ ... }' \\
587
- -d '{ ... }'
588
-
589
- Omit any flag not needed (e.g., omit --path-vars if URL has no placeholders, omit -d for GET).
590
-
591
- Read the API documentation below to identify which parameters are path variables, query parameters, or body fields, then map them to the correct flags above.
592
-
593
- ========================================
594
-
595
- ${knowledge}`;
596
- }
597
545
 
598
546
  // src/lib/cache.ts
599
547
  import fs from "fs";
@@ -601,7 +549,7 @@ import path from "path";
601
549
  function knowledgeDir() {
602
550
  return path.join(homeDir(), ".one", "cache", "knowledge");
603
551
  }
604
- function searchDir() {
552
+ function legacySearchDir() {
605
553
  return path.join(homeDir(), ".one", "cache", "search");
606
554
  }
607
555
  function sanitizeFilename(input) {
@@ -610,10 +558,6 @@ function sanitizeFilename(input) {
610
558
  function knowledgeCachePath(actionId) {
611
559
  return path.join(knowledgeDir(), `${sanitizeFilename(actionId)}.json`);
612
560
  }
613
- function searchCachePath(platform, query, type) {
614
- const key = `${platform}_${sanitizeFilename(query)}_${type || "knowledge"}`;
615
- return path.join(searchDir(), `${key}.json`);
616
- }
617
561
  function readCache(filePath) {
618
562
  try {
619
563
  const content = fs.readFileSync(filePath, "utf-8");
@@ -638,16 +582,6 @@ function isFresh(entry) {
638
582
  function getAge(entry) {
639
583
  return Math.floor((Date.now() - new Date(entry.cachedAt).getTime()) / 1e3);
640
584
  }
641
- function buildCacheMeta(entry, hit) {
642
- if (!entry) {
643
- return { hit: false, age: 0, fresh: false };
644
- }
645
- return {
646
- hit,
647
- age: getAge(entry),
648
- fresh: isFresh(entry)
649
- };
650
- }
651
585
  function formatAge(seconds) {
652
586
  if (seconds < 60) return `${seconds}s`;
653
587
  if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
@@ -662,25 +596,22 @@ function formatAge(seconds) {
662
596
  }
663
597
  function listCacheEntries() {
664
598
  const entries = [];
665
- for (const [dir, type] of [[knowledgeDir(), "knowledge"], [searchDir(), "search"]]) {
666
- try {
667
- const files = fs.readdirSync(dir);
668
- for (const file of files) {
669
- if (!file.endsWith(".json")) continue;
670
- const filePath = path.join(dir, file);
671
- const entry = readCache(filePath);
672
- if (entry) {
673
- entries.push({ type, filePath, entry });
674
- }
599
+ try {
600
+ for (const file of fs.readdirSync(knowledgeDir())) {
601
+ if (!file.endsWith(".json")) continue;
602
+ const filePath = path.join(knowledgeDir(), file);
603
+ const entry = readCache(filePath);
604
+ if (entry) {
605
+ entries.push({ type: "knowledge", filePath, entry });
675
606
  }
676
- } catch {
677
607
  }
608
+ } catch {
678
609
  }
679
610
  return entries;
680
611
  }
681
612
  function clearAll() {
682
613
  let count = 0;
683
- for (const dir of [knowledgeDir(), searchDir()]) {
614
+ for (const dir of [knowledgeDir(), legacySearchDir()]) {
684
615
  try {
685
616
  const files = fs.readdirSync(dir);
686
617
  for (const file of files) {
@@ -821,7 +752,7 @@ var FLOW_SCHEMA = {
821
752
  description: "Execute a platform API action",
822
753
  fields: {
823
754
  platform: { type: "string", required: true, description: "Platform name (kebab-case)" },
824
- actionId: { type: "string", required: true, description: "Action ID from `actions search`" },
755
+ actionId: { type: "string", required: true, description: "Action ID from `actions find`" },
825
756
  connection: { type: "object", required: false, description: "Late-bound connection ref { platform, tag? } \u2014 survives re-auth. Exactly one of `connection` or `connectionKey` must be set." },
826
757
  connectionKey: { type: "string", required: false, description: "Literal connection key (or $.input selector). Legacy form \u2014 prefer `connection: { platform, tag? }`. Exactly one of `connection` or `connectionKey` must be set." },
827
758
  data: { type: "object", required: false, description: "Request body (POST/PUT/PATCH)" },
@@ -1209,7 +1140,7 @@ The only differences: (1) prepend the stdin-read line, (2) replace \`return X\`
1209
1140
 
1210
1141
  1. **Design first** \u2014 clarify the end goal, map the full value chain, identify where AI analysis is needed
1211
1142
  2. **Discover connections** \u2014 \`one --agent connection list\`
1212
- 3. **Get knowledge** for every action \u2014 \`one --agent actions knowledge <platform> <actionId>\`
1143
+ 3. **Find every action with its docs** \u2014 \`one --agent actions find <platform> "<intent>" [<platform> "<intent>" ...]\`, and \`actions load <actionId>\` for more
1213
1144
  4. **Construct JSON** \u2014 declare inputs, wire steps with selectors
1214
1145
  5. **Validate** \u2014 \`one --agent flow validate <key>\`
1215
1146
  6. **Execute** \u2014 \`one --agent flow execute <key> -i param=value\``);
@@ -1534,7 +1465,7 @@ For flows that still use literal \`connectionKey\` strings via inputs, an input
1534
1465
  }
1535
1466
  \`\`\`
1536
1467
 
1537
- Note: Action IDs above are placeholders. Always use \`one --agent actions search <platform> "<query>"\` to find real IDs.
1468
+ Note: Action IDs above are placeholders. Always use \`one --agent actions find <platform> "<intent>"\` to find real IDs.
1538
1469
 
1539
1470
  ## AI-Augmented Pattern
1540
1471
 
@@ -1549,7 +1480,7 @@ Set timeout to at least 180000ms (3 min). Run Claude-heavy flows sequentially, n
1549
1480
  ## Notes
1550
1481
 
1551
1482
  - Connection keys are **inputs**, not hardcoded
1552
- - Action IDs in examples are placeholders \u2014 always use \`actions search\`
1483
+ - Action IDs in examples are placeholders \u2014 always use \`actions find\`
1553
1484
  - Inline \`code.source\` steps allow \`require('crypto' | 'buffer' | 'url' | 'path')\` \u2014 \`fs\`, \`http\`, \`child_process\` are blocked
1554
1485
  - For anything beyond one-liners, use \`code.module\` to point at a \`.mjs\` file in the flow's \`lib/\` folder \u2014 runs as a child \`node\` process with full Node APIs, reads \`$\` from stdin, writes JSON to stdout
1555
1486
  - Bash steps require \`--allow-bash\` flag
@@ -2354,7 +2285,7 @@ async function executeSubflowStep(step, context, api, permissions, allowedAction
2354
2285
  if (flowStack.includes(resolvedKey)) {
2355
2286
  throw new Error(`Circular flow detected: ${[...flowStack, resolvedKey].join(" \u2192 ")}`);
2356
2287
  }
2357
- const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-QQ675PJD.js");
2288
+ const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-L3JG2WCY.js");
2358
2289
  const { flow: subFlow, rootDir: subRootDir } = loadFlowWithMeta2(resolvedKey);
2359
2290
  const subContext = await executeFlow(
2360
2291
  subFlow,
@@ -3274,17 +3205,13 @@ export {
3274
3205
  OneApi,
3275
3206
  TimeoutError,
3276
3207
  PERMISSION_METHODS,
3277
- filterByPermissions,
3278
3208
  isMethodAllowed,
3279
3209
  isActionAllowed,
3280
- buildActionKnowledgeWithGuidance,
3281
3210
  knowledgeCachePath,
3282
- searchCachePath,
3283
3211
  readCache,
3284
3212
  writeCache,
3285
3213
  isFresh,
3286
3214
  getAge,
3287
- buildCacheMeta,
3288
3215
  formatAge,
3289
3216
  listCacheEntries,
3290
3217
  clearAll,
@@ -12,7 +12,7 @@ import {
12
12
  stripStepsAlias,
13
13
  summarizeFlowInputs,
14
14
  walkSteps
15
- } from "./chunk-QCXFSOTS.js";
15
+ } from "./chunk-6EQDEYVD.js";
16
16
  import "./chunk-44CV5IMX.js";
17
17
  import "./chunk-6UB623BG.js";
18
18
  export {