From 66a727aab79bd249d72737771249025ed184b2d6 Mon Sep 17 00:00:00 2001 From: "Paul K." Date: Wed, 14 Oct 2026 13:15:12 -0400 Subject: [PATCH] feat(find): hint for --task and --ai-model in the answer when a find leaves them out (v2.8.0) Co-Authored-By: Claude Opus 5.5 (1M context) --- README.md | 1 + package-lock.json | 4 ++-- package.json | 2 +- skills/one/SKILL.md | 1 + src/commands/actions.ts | 5 ++++- src/lib/find.test.ts | 30 ++++++++++++++++++++++++++++++ src/lib/find.ts | 18 ++++++++++++++++++ src/lib/guide-content.ts | 1 + 8 files changed, 58 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2ad42ea..5b580e2 100644 --- a/README.md +++ b/README.md @@ -269,6 +269,7 @@ one actions find shopify "list products" -t knowledge - **`--task`** describes the whole job in one line, in general terms. Agents are asked to send it with every find, since it helps tell similar actions apart. - **`-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. - **`--ai-model`** names the model running the CLI (e.g. `claude-sonnet-5`), recorded with the find beside the CLI and the harness that launched it, so the account's usage can report which model asked. Agents are asked to send it with every find. +- An answer to a find without `--task` or `--ai-model` carries a `hint` field (a dim line for humans) asking for them on the next find. Both stay optional. - **`--no-knowledge`** lists the chosen actions (actionId, title, method, path) without fetching their documentation; load it later with `one actions load `. 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. diff --git a/package-lock.json b/package-lock.json index 464c3be..fd4600c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@withone/cli", - "version": "2.7.1", + "version": "2.8.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@withone/cli", - "version": "2.7.1", + "version": "2.8.0", "dependencies": { "@clack/prompts": "^0.9.1", "commander": "^13.1.0", diff --git a/package.json b/package.json index b9e1e9a..6814a9d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withone/cli", - "version": "2.7.1", + "version": "2.8.0", "description": "CLI for managing One", "type": "module", "files": [ diff --git a/skills/one/SKILL.md b/skills/one/SKILL.md index bbac199..778c2e0 100644 --- a/skills/one/SKILL.md +++ b/skills/one/SKILL.md @@ -85,6 +85,7 @@ one --agent actions find "" [ "" ...] --tas - **`--task`**: send it with every find. It is the whole job in one line, **in general terms**: `"email a weather report to a contact"`, without names, addresses, IDs, or message text. It helps tell similar actions apart. - **`-t knowledge`** searches the catalog for writing code and building flows and relays (it includes the platform's own passthrough endpoints); the default, `-t execute`, is the catalog for running actions now. - **`--ai-model`**: send it with every find. Your model name as you know it (e.g. `claude-sonnet-5`), recorded with the find; leave it out only if you do not know which model you are. +- A find answer sent without either carries a **`hint`** naming what was missing: add it on your next find. - **`--no-knowledge`** (optional): list the chosen actions without their documentation, when you only need the actionIds. Load the documentation with `actions load` before executing. - Platform names are lowercase; multi-word names use dashes: `gmail`, `hubspot`, `ship-station`, `google-calendar`. diff --git a/src/commands/actions.ts b/src/commands/actions.ts index f5e5158..ef7e3db 100644 --- a/src/commands/actions.ts +++ b/src/commands/actions.ts @@ -13,6 +13,7 @@ import { type FindDeps, type FindSettings, type LoadOptions, + findHint, } from '../lib/find.js'; import { knowledgeCachePath, readCache, isFresh, getAge, formatAge } from '../lib/cache.js'; @@ -107,13 +108,15 @@ export async function actionsFindCommand(pairs: string[], options: ActionsFindOp { knowledgeCatalog: options.type === 'knowledge', knowledge: options.knowledge !== false } ); + const hint = findHint(options.task, options.aiModel); if (output.isAgentMode()) { - output.json(result); + output.json(hint ? { ...result, hint } : result); return; } spinner.stop('Found'); console.log(); console.log(renderFind(result)); + if (hint) console.log(`\n${pc.dim(hint)}`); console.log(); } catch (error) { spinner.stop('Find failed'); diff --git a/src/lib/find.test.ts b/src/lib/find.test.ts index b87946f..ca448d1 100644 --- a/src/lib/find.test.ts +++ b/src/lib/find.test.ts @@ -6,6 +6,7 @@ import { FindArgsError, REFUSED_LOAD, find, + findHint, load, renderFind, type DocumentedAction, @@ -286,3 +287,32 @@ describe('actions load', () => { assert.equal((result.loaded[1] as DocumentedAction).knowledge, huge); }); }); + +describe('find hint', () => { + it('asks for the task and the model when a find carries neither', () => { + const hint = findHint(undefined, undefined); + assert.ok(hint); + assert.match(hint, /--task/); + assert.match(hint, /--ai-model/); + }); + + it('names only what is missing', () => { + const noTask = findHint(undefined, 'claude-sonnet-5'); + assert.ok(noTask); + assert.match(noTask, /--task/); + assert.doesNotMatch(noTask, /--ai-model/); + + const noModel = findHint('email a report to a contact', undefined); + assert.ok(noModel); + assert.match(noModel, /--ai-model/); + assert.doesNotMatch(noModel, /--task/); + }); + + it('treats a blank value as missing', () => { + assert.match(findHint(' ', 'claude-sonnet-5') ?? '', /--task/); + }); + + it('says nothing when both were sent', () => { + assert.equal(findHint('email a report to a contact', 'claude-sonnet-5'), undefined); + }); +}); diff --git a/src/lib/find.ts b/src/lib/find.ts index 773b944..90173b8 100644 --- a/src/lib/find.ts +++ b/src/lib/find.ts @@ -110,6 +110,24 @@ export interface FindResult { answers: FindAnswer[]; /** What applies to every documented action, stated once: how to execute, or the code guide's rules. */ guide?: string; + /** Set when the find came without `--task` or `--ai-model`: asks for them on the next find (see {@link findHint}). */ + hint?: string; +} + +/** + * What a find should have carried, said back to the agent in its answer: the + * task (it helps tell similar actions apart) and the model (recorded with the + * find). Agents that never read the skill still read the answer, so this is + * where the ask reaches them. Undefined when both were sent; a blank value + * counts as missing. Never blocks a find: both stay optional. + */ +export function findHint(task?: string, aiModel?: string): string | undefined { + const missing = [ + task?.trim() ? null : '--task ""', + aiModel?.trim() ? null : '--ai-model ""', + ].filter((m): m is string => m !== null); + if (missing.length === 0) return undefined; + return `Send ${missing.join(' and ')} with every find: the task helps tell similar actions apart, and both are recorded with the find.`; } /** One `actions load` entry's outcome. */ diff --git a/src/lib/guide-content.ts b/src/lib/guide-content.ts index fde5f79..d91b1e7 100644 --- a/src/lib/guide-content.ts +++ b/src/lib/guide-content.ts @@ -183,6 +183,7 @@ One call for the whole task: one platform and intent pair per operation, on any - **\`--task\`**: send it with every find. It is the whole job in one line, **in general terms**: what it does, without names, addresses, IDs, or message text. It helps tell similar actions apart. - **\`-t knowledge\`** searches the catalog for writing code and building flows and relays, which includes the platform's own (passthrough) endpoints; the default, \`-t execute\`, is the catalog for running actions now. Knowledge-only mode always uses \`knowledge\`. - **\`--ai-model\`**: send it with every find. Your model name as you know it (e.g. \`claude-sonnet-5\`), recorded with the find; leave it out only if you do not know which model you are. +- A find answer sent without either carries a **\`hint\`** naming what was missing: add it on your next find. - **\`--no-knowledge\`** (optional) lists the chosen actions without their documentation, when only the actionIds are needed. Load the documentation with \`actions load\` before executing. In \`--agent\` mode: