From 405fd6ca3490982ff0807313d7c8203a88184362 Mon Sep 17 00:00:00 2001 From: zbigniew sobiecki Date: Sun, 18 Jan 2026 09:51:02 +0100 Subject: [PATCH 1/2] feat(gadgets): add required comment parameter to all gadgets Add a required `comment` string parameter to all 23 gadgets so agents must explain the rationale behind each gadget call. This improves observability and debugging of agent sessions. Changes: - Add `comment: z.string().min(1)` to all gadget schemas - Update all gadget examples to include comment field - Log comment field (unabbreviated) in gadget call logs - Update synthetic gadget calls in agents with pre-fetch comments - Add todo list to implementation agent's trailing message - Replace `reason` with `comment` in Sleep gadget - Rename `comment` to `text` in PostTrelloComment to avoid collision Co-Authored-By: Claude Opus 4.5 --- src/agents/base.ts | 27 ++++++++++---- src/agents/respond-to-review.ts | 29 ++++++++++----- src/agents/review.ts | 24 ++++++++----- src/agents/utils/agentLoop.ts | 5 +++ src/config/hintConfig.ts | 42 +++++++++++++++++----- src/gadgets/EditFile.ts | 4 +++ src/gadgets/ListDirectory.ts | 15 ++++++-- src/gadgets/ReadFile.ts | 8 +++-- src/gadgets/Sleep.ts | 17 +++++---- src/gadgets/WriteFile.ts | 13 +++++-- src/gadgets/github/CreatePR.ts | 4 +++ src/gadgets/github/CreatePRReview.ts | 3 ++ src/gadgets/github/GetPRChecks.ts | 2 ++ src/gadgets/github/GetPRComments.ts | 2 ++ src/gadgets/github/GetPRDetails.ts | 2 ++ src/gadgets/github/GetPRDiff.ts | 2 ++ src/gadgets/github/ReplyToReviewComment.ts | 2 ++ src/gadgets/tmux.ts | 37 ++++++++++++++++--- src/gadgets/todo/TodoDelete.ts | 3 +- src/gadgets/todo/TodoUpsert.ts | 11 ++++-- src/gadgets/trello/AddChecklistToCard.ts | 3 ++ src/gadgets/trello/CreateTrelloCard.ts | 3 ++ src/gadgets/trello/GetMyRecentActivity.ts | 5 +-- src/gadgets/trello/ListTrelloCards.ts | 3 +- src/gadgets/trello/PostTrelloComment.ts | 9 ++--- src/gadgets/trello/ReadTrelloCard.ts | 13 +++++-- src/gadgets/trello/UpdateChecklistItem.ts | 3 ++ src/gadgets/trello/UpdateTrelloCard.ts | 3 ++ 28 files changed, 227 insertions(+), 67 deletions(-) diff --git a/src/agents/base.ts b/src/agents/base.ts index 081d0d4a..54f91df5 100644 --- a/src/agents/base.ts +++ b/src/agents/base.ts @@ -316,6 +316,7 @@ function createAgentBuilderWithGadgets( .withRetry(getRetryConfig(llmistLogger)) .withCompaction(getCompactionConfig(agentType)) .withTrailingMessage(getIterationTrailingMessage(agentType)) + .withTextOnlyHandler('acknowledge') .withHooks({ observers: createObserverHooks({ model: ctx.model, @@ -349,7 +350,12 @@ async function injectSyntheticCalls( // Call the actual gadget to generate output (respects .gitignore by default) // Use maxDepth=5 to give agents better visibility into nested structures const listDirGadget = new ListDirectory(); - const listDirParams = { directoryPath: '.', maxDepth: 5, includeGitIgnored: false }; + const listDirParams = { + comment: 'Pre-fetching codebase structure for context', + directoryPath: '.', + maxDepth: 5, + includeGitIgnored: false, + }; const listDirResult = listDirGadget.execute(listDirParams); recordSyntheticInvocationId(trackingContext, 'gc_dir'); builder = builder.withSyntheticGadgetCall( @@ -364,7 +370,7 @@ async function injectSyntheticCalls( recordSyntheticInvocationId(trackingContext, 'gc_card'); builder = builder.withSyntheticGadgetCall( 'ReadTrelloCard', - { cardId, includeComments: true }, + { comment: 'Pre-fetching card data for task context', cardId, includeComments: true }, cardData, 'gc_card', ); @@ -377,7 +383,7 @@ async function injectSyntheticCalls( recordSyntheticInvocationId(trackingContext, invocationId); builder = builder.withSyntheticGadgetCall( 'ReadFile', - { filePath: file.path }, + { comment: `Pre-fetching ${file.path} for project context`, filePath: file.path }, file.content, invocationId, ); @@ -385,24 +391,31 @@ async function injectSyntheticCalls( // Inject AU understanding if enabled (gives agent immediate codebase context) if (auEnabled) { - const auListResult = (await auList.execute({ path: '.', maxDepth: 5 })) as string; + const auListResult = (await auList.execute({ + comment: 'Pre-fetching AU entries for context', + path: '.', + maxDepth: 5, + })) as string; // Only inject if there's actual content if (auListResult && !auListResult.includes('No AU entries found')) { recordSyntheticInvocationId(trackingContext, 'gc_au_list'); builder = builder.withSyntheticGadgetCall( 'AUList', - { path: '.', maxDepth: 5 }, + { comment: 'Pre-fetching AU entries for context', path: '.', maxDepth: 5 }, auListResult, 'gc_au_list', ); // Also inject root-level understanding for high-level context - const auReadResult = (await auRead.execute({ paths: '.' })) as string; + const auReadResult = (await auRead.execute({ + comment: 'Pre-fetching root-level understanding', + paths: '.', + })) as string; if (auReadResult && !auReadResult.includes('No understanding exists yet')) { recordSyntheticInvocationId(trackingContext, 'gc_au_read'); builder = builder.withSyntheticGadgetCall( 'AURead', - { paths: '.' }, + { comment: 'Pre-fetching root-level understanding', paths: '.' }, auReadResult, 'gc_au_read', ); diff --git a/src/agents/respond-to-review.ts b/src/agents/respond-to-review.ts index 04cce8a8..9098c34c 100644 --- a/src/agents/respond-to-review.ts +++ b/src/agents/respond-to-review.ts @@ -308,7 +308,12 @@ async function injectReviewSyntheticCalls( // Inject directory listing as synthetic ListDirectory call (first for codebase orientation) // Call the actual gadget to generate output (respects .gitignore by default) const listDirGadget = new ListDirectory(); - const listDirParams = { directoryPath: '.', maxDepth: 3, includeGitIgnored: false }; + const listDirParams = { + comment: 'Pre-fetching codebase structure for context', + directoryPath: '.', + maxDepth: 3, + includeGitIgnored: false, + }; const listDirResult = listDirGadget.execute(listDirParams); recordSyntheticInvocationId(trackingContext, 'gc_dir'); builder = builder.withSyntheticGadgetCall( @@ -322,7 +327,7 @@ async function injectReviewSyntheticCalls( recordSyntheticInvocationId(trackingContext, 'gc_pr_details'); builder = builder.withSyntheticGadgetCall( 'GetPRDetails', - { owner, repo, prNumber }, + { comment: 'Pre-fetching PR details for context', owner, repo, prNumber }, ctx.prDetailsFormatted, 'gc_pr_details', ); @@ -331,7 +336,7 @@ async function injectReviewSyntheticCalls( recordSyntheticInvocationId(trackingContext, 'gc_pr_comments'); builder = builder.withSyntheticGadgetCall( 'GetPRComments', - { owner, repo, prNumber }, + { comment: 'Pre-fetching review comments to address', owner, repo, prNumber }, ctx.commentsFormatted, 'gc_pr_comments', ); @@ -340,7 +345,7 @@ async function injectReviewSyntheticCalls( recordSyntheticInvocationId(trackingContext, 'gc_pr_diff'); builder = builder.withSyntheticGadgetCall( 'GetPRDiff', - { owner, repo, prNumber }, + { comment: 'Pre-fetching PR diff for context', owner, repo, prNumber }, ctx.diffFormatted, 'gc_pr_diff', ); @@ -352,7 +357,7 @@ async function injectReviewSyntheticCalls( recordSyntheticInvocationId(trackingContext, invocationId); builder = builder.withSyntheticGadgetCall( 'ReadFile', - { filePath: file.path }, + { comment: `Pre-fetching ${file.path} for project context`, filePath: file.path }, file.content, invocationId, ); @@ -360,24 +365,30 @@ async function injectReviewSyntheticCalls( // Inject AU understanding if enabled (gives agent immediate codebase context) if (auEnabled) { - const auListResult = (await auList.execute({ path: '.' })) as string; + const auListResult = (await auList.execute({ + comment: 'Pre-fetching AU entries for context', + path: '.', + })) as string; // Only inject if there's actual content if (auListResult && !auListResult.includes('No AU entries found')) { recordSyntheticInvocationId(trackingContext, 'gc_au_list'); builder = builder.withSyntheticGadgetCall( 'AUList', - { path: '.' }, + { comment: 'Pre-fetching AU entries for context', path: '.' }, auListResult, 'gc_au_list', ); // Also inject root-level understanding for high-level context - const auReadResult = (await auRead.execute({ paths: '.' })) as string; + const auReadResult = (await auRead.execute({ + comment: 'Pre-fetching root-level understanding', + paths: '.', + })) as string; if (auReadResult && !auReadResult.includes('No understanding exists yet')) { recordSyntheticInvocationId(trackingContext, 'gc_au_read'); builder = builder.withSyntheticGadgetCall( 'AURead', - { paths: '.' }, + { comment: 'Pre-fetching root-level understanding', paths: '.' }, auReadResult, 'gc_au_read', ); diff --git a/src/agents/review.ts b/src/agents/review.ts index ae4762b5..6f7ea810 100644 --- a/src/agents/review.ts +++ b/src/agents/review.ts @@ -299,7 +299,7 @@ async function injectReviewSyntheticCalls( recordSyntheticInvocationId(trackingContext, 'gc_pr_details'); builder = builder.withSyntheticGadgetCall( 'GetPRDetails', - { owner, repo, prNumber }, + { comment: 'Pre-fetching PR details for review context', owner, repo, prNumber }, ctx.prDetailsFormatted, 'gc_pr_details', ); @@ -308,7 +308,7 @@ async function injectReviewSyntheticCalls( recordSyntheticInvocationId(trackingContext, 'gc_pr_diff'); builder = builder.withSyntheticGadgetCall( 'GetPRDiff', - { owner, repo, prNumber }, + { comment: 'Pre-fetching PR diff for code review', owner, repo, prNumber }, ctx.diffFormatted, 'gc_pr_diff', ); @@ -317,7 +317,7 @@ async function injectReviewSyntheticCalls( recordSyntheticInvocationId(trackingContext, 'gc_pr_checks'); builder = builder.withSyntheticGadgetCall( 'GetPRChecks', - { owner, repo, prNumber }, + { comment: 'Pre-fetching CI check status for review', owner, repo, prNumber }, ctx.checkStatusFormatted, 'gc_pr_checks', ); @@ -329,7 +329,7 @@ async function injectReviewSyntheticCalls( recordSyntheticInvocationId(trackingContext, invocationId); builder = builder.withSyntheticGadgetCall( 'ReadFile', - { filePath: file.path }, + { comment: `Pre-fetching ${file.path} for project context`, filePath: file.path }, file.content, invocationId, ); @@ -342,7 +342,7 @@ async function injectReviewSyntheticCalls( recordSyntheticInvocationId(trackingContext, invocationId); builder = builder.withSyntheticGadgetCall( 'ReadFile', - { filePath: file.path }, + { comment: `Pre-fetching ${file.path} for review`, filePath: file.path }, `path=${file.path}\n\n${file.content}`, invocationId, ); @@ -350,24 +350,30 @@ async function injectReviewSyntheticCalls( // Inject AU understanding if enabled (gives agent immediate codebase context) if (auEnabled) { - const auListResult = (await auList.execute({ path: '.' })) as string; + const auListResult = (await auList.execute({ + comment: 'Pre-fetching AU entries for context', + path: '.', + })) as string; // Only inject if there's actual content if (auListResult && !auListResult.includes('No AU entries found')) { recordSyntheticInvocationId(trackingContext, 'gc_au_list'); builder = builder.withSyntheticGadgetCall( 'AUList', - { path: '.' }, + { comment: 'Pre-fetching AU entries for context', path: '.' }, auListResult, 'gc_au_list', ); // Also inject root-level understanding for high-level context - const auReadResult = (await auRead.execute({ paths: '.' })) as string; + const auReadResult = (await auRead.execute({ + comment: 'Pre-fetching root-level understanding', + paths: '.', + })) as string; if (auReadResult && !auReadResult.includes('No understanding exists yet')) { recordSyntheticInvocationId(trackingContext, 'gc_au_read'); builder = builder.withSyntheticGadgetCall( 'AURead', - { paths: '.' }, + { comment: 'Pre-fetching root-level understanding', paths: '.' }, auReadResult, 'gc_au_read', ); diff --git a/src/agents/utils/agentLoop.ts b/src/agents/utils/agentLoop.ts index 2003de24..9b897a8c 100644 --- a/src/agents/utils/agentLoop.ts +++ b/src/agents/utils/agentLoop.ts @@ -151,6 +151,11 @@ async function handleGadgetCallEvent( logContext.isSynthetic = true; } + // Include the comment field (unabbreviated) for observability + if (parameters?.comment) { + logContext.comment = parameters.comment; + } + addGadgetSpecificLogContext(logContext, gadgetName, parameters); log.info('[Gadget]', logContext); } diff --git a/src/config/hintConfig.ts b/src/config/hintConfig.ts index f764e9ba..e26aa7a6 100644 --- a/src/config/hintConfig.ts +++ b/src/config/hintConfig.ts @@ -1,4 +1,5 @@ import type { TrailingMessage } from 'llmist'; +import { formatTodoList, loadTodos } from '../gadgets/todo/storage.js'; /** * Agent-specific batch hints. @@ -32,6 +33,28 @@ function getAgentHint(agentType?: string): string { return AGENT_HINTS.default; } +/** + * Format the iteration status line with appropriate urgency indicator. + */ +function formatIterationStatus( + iteration: number, + maxIterations: number, + batchHint: string, +): string { + const remaining = maxIterations - iteration; + const percent = Math.round((iteration / maxIterations) * 100); + + if (percent >= 80) { + return `🚨 Iteration ${iteration}/${maxIterations} (${percent}% used, ${remaining} remaining) - ${batchHint}`; + } + + if (percent >= 50) { + return `āš ļø Iteration ${iteration}/${maxIterations} (${percent}% used, ${remaining} remaining) - ${batchHint}`; + } + + return `Iteration ${iteration}/${maxIterations} (${percent}% used, ${remaining} remaining) - ${batchHint}`; +} + /** * Get trailing message function for iteration tracking. * @@ -39,6 +62,7 @@ function getAgentHint(agentType?: string): string { * - Always shows current iteration, remaining count, and percentage * - Adds urgency indicator when running low on iterations * - Includes agent-specific batch processing hints + * - For implementation agent: includes current todo list for visibility * * Trailing messages are ephemeral - they appear in each request but don't * persist to conversation history, keeping context clean. @@ -50,17 +74,17 @@ export function getIterationTrailingMessage(agentType?: string): TrailingMessage const batchHint = getAgentHint(agentType); return (ctx) => { - const remaining = ctx.maxIterations - ctx.iteration; - const percent = Math.round((ctx.iteration / ctx.maxIterations) * 100); - - if (percent >= 80) { - return `🚨 Iteration ${ctx.iteration}/${ctx.maxIterations} (${percent}% used, ${remaining} remaining) - ${batchHint}`; - } + const iterationStatus = formatIterationStatus(ctx.iteration, ctx.maxIterations, batchHint); - if (percent >= 50) { - return `āš ļø Iteration ${ctx.iteration}/${ctx.maxIterations} (${percent}% used, ${remaining} remaining) - ${batchHint}`; + // For implementation agent, include the current todo list + if (agentType === 'implementation') { + const todos = loadTodos(); + if (todos.length > 0) { + const todoListFormatted = formatTodoList(todos); + return `${iterationStatus}\n\n## Current Progress\n\n${todoListFormatted}`; + } } - return `Iteration ${ctx.iteration}/${ctx.maxIterations} (${percent}% used, ${remaining} remaining) - ${batchHint}`; + return iterationStatus; }; } diff --git a/src/gadgets/EditFile.ts b/src/gadgets/EditFile.ts index c78974b7..41f1b636 100644 --- a/src/gadgets/EditFile.ts +++ b/src/gadgets/EditFile.ts @@ -60,6 +60,7 @@ Each call provides immediate feedback, allowing you to adjust subsequent edits.` timeoutMs: 30000, maxConcurrent: 1, // Sequential execution to prevent race conditions on file writes schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), filePath: z.string().describe('Path to the file to edit (relative or absolute)'), search: z.string().describe('The content to search for in the file'), replace: z.string().describe('The content to replace it with (empty string to delete)'), @@ -67,6 +68,7 @@ Each call provides immediate feedback, allowing you to adjust subsequent edits.` examples: [ { params: { + comment: 'Increasing timeout from 1s to 5s to fix test flakiness', filePath: 'src/config.ts', search: 'timeout: 1000', replace: 'timeout: 5000', @@ -103,6 +105,7 @@ No lint issues found.`, }, { params: { + comment: 'Updating retry constant per requirements', filePath: 'src/constants.ts', search: 'MAX_RETRIES = 3', replace: 'MAX_RETRIES = 5', @@ -150,6 +153,7 @@ No lint issues found.`, }, { params: { + comment: 'Enabling feature flag for new functionality', filePath: 'src/data.json', search: '"enabled": false', replace: '"enabled": true', diff --git a/src/gadgets/ListDirectory.ts b/src/gadgets/ListDirectory.ts index bdca53e3..76c89775 100644 --- a/src/gadgets/ListDirectory.ts +++ b/src/gadgets/ListDirectory.ts @@ -251,6 +251,7 @@ Allowed paths: - Current working directory and subdirectories - /tmp directory`, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), directoryPath: z.string().default('.').describe('Path to the directory to list'), maxDepth: z .number() @@ -266,13 +267,23 @@ Allowed paths: }), examples: [ { - params: { directoryPath: '.', maxDepth: 1, includeGitIgnored: false }, + params: { + comment: 'Getting overview of project structure', + directoryPath: '.', + maxDepth: 1, + includeGitIgnored: false, + }, output: 'path=. maxDepth=1 includeGitIgnored=false\n\n#T|N|S|A\nD|src|0|2h\nD|tests|0|1d\nF|package.json|2841|3h', comment: 'List current directory (excluding gitignored files)', }, { - params: { directoryPath: 'src', maxDepth: 2, includeGitIgnored: true }, + params: { + comment: 'Exploring src directory to find component files', + directoryPath: 'src', + maxDepth: 2, + includeGitIgnored: true, + }, output: 'path=src maxDepth=2 includeGitIgnored=true\n\n#T|N|S|A\nD|components|0|1d\nF|index.ts|512|1h', comment: 'List src directory including all files', diff --git a/src/gadgets/ReadFile.ts b/src/gadgets/ReadFile.ts index 0f9b0ed9..a9309601 100644 --- a/src/gadgets/ReadFile.ts +++ b/src/gadgets/ReadFile.ts @@ -57,6 +57,7 @@ Allowed paths: - Current working directory and subdirectories - /tmp directory (for test logs, build artifacts, etc.)`, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), filePath: z .string() .describe( @@ -65,12 +66,15 @@ Allowed paths: }), examples: [ { - params: { filePath: 'package.json' }, + params: { + comment: 'Reading config to understand project structure', + filePath: 'package.json', + }, output: 'path=package.json\n\n{\n "name": "my-project",\n "version": "1.0.0"\n ...\n}', comment: 'Read a JSON config file', }, { - params: { filePath: '/tmp/test.log' }, + params: { comment: 'Checking test output for failures', filePath: '/tmp/test.log' }, output: 'path=/tmp/test.log\n\n[Test output...]', comment: 'Read a test log from /tmp', }, diff --git a/src/gadgets/Sleep.ts b/src/gadgets/Sleep.ts index d19e0fdf..56e668b9 100644 --- a/src/gadgets/Sleep.ts +++ b/src/gadgets/Sleep.ts @@ -23,36 +23,35 @@ export class Sleep extends Gadget({ - Don't use for long waits (>30s) - prefer polling with shorter sleeps`, timeoutMs: 65000, // Allow up to 60s sleep + 5s buffer schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), seconds: z.number().min(0.1).max(60).describe('Duration to sleep in seconds (0.1 to 60)'), - reason: z.string().optional().describe('Optional reason for the wait (for logging clarity)'), }), examples: [ { - params: { seconds: 3, reason: 'waiting for dev server to start' }, - output: 'Slept for 3 seconds (waiting for dev server to start)', + params: { comment: 'Waiting for dev server to start', seconds: 3 }, + output: 'Slept for 3 seconds', comment: 'Wait for a dev server after starting it with tmux', }, { - params: { seconds: 1 }, + params: { comment: 'Brief pause between operations', seconds: 1 }, output: 'Slept for 1 second', comment: 'Brief pause between operations', }, { - params: { seconds: 5, reason: 'database initialization' }, - output: 'Slept for 5 seconds (database initialization)', + params: { comment: 'Waiting for database initialization', seconds: 5 }, + output: 'Slept for 5 seconds', comment: 'Wait for database to be ready', }, ], }) { override async execute(params: this['params']): Promise { - const { seconds, reason } = params; + const { seconds } = params; // Sleep for the specified duration await new Promise((resolve) => setTimeout(resolve, seconds * 1000)); const duration = seconds === 1 ? '1 second' : `${seconds} seconds`; - const reasonText = reason ? ` (${reason})` : ''; - return `Slept for ${duration}${reasonText}`; + return `Slept for ${duration}`; } } diff --git a/src/gadgets/WriteFile.ts b/src/gadgets/WriteFile.ts index f53b1196..5c8c412e 100644 --- a/src/gadgets/WriteFile.ts +++ b/src/gadgets/WriteFile.ts @@ -61,17 +61,26 @@ Allowed paths: - Current working directory and subdirectories - /tmp directory`, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), filePath: z.string().describe('Path to the file to write (relative or absolute)'), content: z.string().describe('Content to write to the file'), }), examples: [ { - params: { filePath: 'output.txt', content: 'Hello, World!' }, + params: { + comment: 'Creating output file for test results', + filePath: 'output.txt', + content: 'Hello, World!', + }, output: 'path=output.txt\n\nWrote 13 bytes', comment: 'Write a simple text file (no diagnostics for non-TS files)', }, { - params: { filePath: 'src/utils/helper.ts', content: 'export function helper() {}' }, + params: { + comment: 'Adding new helper utility function', + filePath: 'src/utils/helper.ts', + content: 'export function helper() {}', + }, output: `path=src/utils/helper.ts Wrote 27 bytes (created directory: src/utils) diff --git a/src/gadgets/github/CreatePR.ts b/src/gadgets/github/CreatePR.ts index 9c7bb986..cc474b3d 100644 --- a/src/gadgets/github/CreatePR.ts +++ b/src/gadgets/github/CreatePR.ts @@ -24,6 +24,7 @@ NOTE: Pre-commit and pre-push hooks may run tests which can take time. If hooks fail or timeout, the full output will be shown.`, timeoutMs: 240000, // 4 minutes - hooks may run test suites schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), owner: z.string().describe('The repository owner (username or organization)'), repo: z.string().describe('The repository name'), title: z @@ -48,6 +49,7 @@ If hooks fail or timeout, the full output will be shown.`, examples: [ { params: { + comment: 'Creating PR for completed auth feature', owner: 'acme', repo: 'myapp', title: 'feat: add user authentication', @@ -59,6 +61,7 @@ If hooks fail or timeout, the full output will be shown.`, }, { params: { + comment: 'Creating draft PR for early feedback', owner: 'acme', repo: 'myapp', title: 'fix: resolve null pointer in checkout', @@ -72,6 +75,7 @@ If hooks fail or timeout, the full output will be shown.`, }, { params: { + comment: 'Creating PR - already committed and pushed', owner: 'acme', repo: 'myapp', title: 'chore: update dependencies', diff --git a/src/gadgets/github/CreatePRReview.ts b/src/gadgets/github/CreatePRReview.ts index 10dc8002..91fb2b83 100644 --- a/src/gadgets/github/CreatePRReview.ts +++ b/src/gadgets/github/CreatePRReview.ts @@ -8,6 +8,7 @@ export class CreatePRReview extends Gadget({ 'Submit a code review on a GitHub pull request. Use this to approve, request changes, or comment on the PR.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), owner: z.string().describe('The repository owner (username or organization)'), repo: z.string().describe('The repository name'), prNumber: z.number().describe('The pull request number'), @@ -29,6 +30,7 @@ export class CreatePRReview extends Gadget({ examples: [ { params: { + comment: 'Approving PR after thorough review', owner: 'acme', repo: 'myapp', prNumber: 42, @@ -39,6 +41,7 @@ export class CreatePRReview extends Gadget({ }, { params: { + comment: 'Requesting changes for identified issues', owner: 'acme', repo: 'myapp', prNumber: 42, diff --git a/src/gadgets/github/GetPRChecks.ts b/src/gadgets/github/GetPRChecks.ts index 9b53673a..5925871d 100644 --- a/src/gadgets/github/GetPRChecks.ts +++ b/src/gadgets/github/GetPRChecks.ts @@ -57,6 +57,7 @@ export class GetPRChecks extends Gadget({ 'Get the CI check status for a GitHub pull request. Shows all workflow runs and their status/conclusion.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), owner: z.string().describe('The repository owner (username or organization)'), repo: z.string().describe('The repository name'), prNumber: z.number().describe('The pull request number'), @@ -64,6 +65,7 @@ export class GetPRChecks extends Gadget({ examples: [ { params: { + comment: 'Checking CI status before merge', owner: 'acme', repo: 'myapp', prNumber: 42, diff --git a/src/gadgets/github/GetPRComments.ts b/src/gadgets/github/GetPRComments.ts index 47686047..5444ef9e 100644 --- a/src/gadgets/github/GetPRComments.ts +++ b/src/gadgets/github/GetPRComments.ts @@ -8,6 +8,7 @@ export class GetPRComments extends Gadget({ 'Get all review comments on a GitHub pull request. Use this to understand what feedback has been given.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), owner: z.string().describe('The repository owner (username or organization)'), repo: z.string().describe('The repository name'), prNumber: z.number().describe('The pull request number'), @@ -15,6 +16,7 @@ export class GetPRComments extends Gadget({ examples: [ { params: { + comment: 'Fetching review comments to understand feedback', owner: 'acme', repo: 'myapp', prNumber: 42, diff --git a/src/gadgets/github/GetPRDetails.ts b/src/gadgets/github/GetPRDetails.ts index 4e2d29c7..1724768c 100644 --- a/src/gadgets/github/GetPRDetails.ts +++ b/src/gadgets/github/GetPRDetails.ts @@ -8,6 +8,7 @@ export class GetPRDetails extends Gadget({ 'Get details about a GitHub pull request including title, description, and branch info.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), owner: z.string().describe('The repository owner (username or organization)'), repo: z.string().describe('The repository name'), prNumber: z.number().describe('The pull request number'), @@ -15,6 +16,7 @@ export class GetPRDetails extends Gadget({ examples: [ { params: { + comment: 'Fetching PR details to understand changes', owner: 'acme', repo: 'myapp', prNumber: 42, diff --git a/src/gadgets/github/GetPRDiff.ts b/src/gadgets/github/GetPRDiff.ts index 14b31aa2..e2de6ace 100644 --- a/src/gadgets/github/GetPRDiff.ts +++ b/src/gadgets/github/GetPRDiff.ts @@ -8,6 +8,7 @@ export class GetPRDiff extends Gadget({ 'Get the unified diff of all file changes in a GitHub pull request. Shows each file with additions, deletions, and the patch content.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), owner: z.string().describe('The repository owner (username or organization)'), repo: z.string().describe('The repository name'), prNumber: z.number().describe('The pull request number'), @@ -15,6 +16,7 @@ export class GetPRDiff extends Gadget({ examples: [ { params: { + comment: 'Reviewing file changes for code review', owner: 'acme', repo: 'myapp', prNumber: 42, diff --git a/src/gadgets/github/ReplyToReviewComment.ts b/src/gadgets/github/ReplyToReviewComment.ts index 4296e593..be45f858 100644 --- a/src/gadgets/github/ReplyToReviewComment.ts +++ b/src/gadgets/github/ReplyToReviewComment.ts @@ -8,6 +8,7 @@ export class ReplyToReviewComment extends Gadget({ 'Reply to a specific review comment on a GitHub pull request. Use this to acknowledge feedback and explain what was fixed.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), owner: z.string().describe('The repository owner (username or organization)'), repo: z.string().describe('The repository name'), prNumber: z.number().describe('The pull request number'), @@ -17,6 +18,7 @@ export class ReplyToReviewComment extends Gadget({ examples: [ { params: { + comment: 'Responding to review feedback about edge cases', owner: 'acme', repo: 'myapp', prNumber: 42, diff --git a/src/gadgets/tmux.ts b/src/gadgets/tmux.ts index b3827b09..366cde8f 100644 --- a/src/gadgets/tmux.ts +++ b/src/gadgets/tmux.ts @@ -628,6 +628,7 @@ Commands are interpreted by bash, so pipes, &&, ||, redirects, and globs all wor schema: z.discriminatedUnion('action', [ z.object({ action: z.literal('start'), + comment: z.string().min(1).describe('Brief rationale for this gadget call'), session: sessionNameSchema.describe("Unique session name (e.g., 'test-run', 'npm-install')"), command: z .string() @@ -641,6 +642,7 @@ Commands are interpreted by bash, so pipes, &&, ||, redirects, and globs all wor }), z.object({ action: z.literal('send'), + comment: z.string().min(1).describe('Brief rationale for this gadget call'), session: sessionNameSchema.describe('Target session name'), keys: z.string().describe("Keys or command to send (e.g., 'npm test' or 'C-c' for Ctrl+C)"), enter: z.coerce @@ -650,6 +652,7 @@ Commands are interpreted by bash, so pipes, &&, ||, redirects, and globs all wor }), z.object({ action: z.literal('capture'), + comment: z.string().min(1).describe('Brief rationale for this gadget call'), session: sessionNameSchema.describe('Session to capture output from'), lines: z.coerce .number() @@ -661,19 +664,28 @@ Commands are interpreted by bash, so pipes, &&, ||, redirects, and globs all wor }), z.object({ action: z.literal('list'), + comment: z.string().min(1).describe('Brief rationale for this gadget call'), }), z.object({ action: z.literal('kill'), + comment: z.string().min(1).describe('Brief rationale for this gadget call'), session: sessionNameSchema.describe('Session to terminate'), }), z.object({ action: z.literal('exists'), + comment: z.string().min(1).describe('Brief rationale for this gadget call'), session: sessionNameSchema.describe('Session name to check'), }), ]), examples: [ { - params: { action: 'start', session: 'test-run', command: 'npm test', wait: 120000 }, + params: { + action: 'start', + comment: 'Running unit tests to verify changes', + session: 'test-run', + command: 'npm test', + wait: 120000, + }, output: 'session=test-run status=exited exit_code=0\n\n> project@1.0.0 test\n> vitest run\n\nāœ“ 15 tests passed', comment: 'Run tests - command completed within 120s wait period', @@ -681,6 +693,7 @@ Commands are interpreted by bash, so pipes, &&, ||, redirects, and globs all wor { params: { action: 'start', + comment: 'Running lint and tests in sequence', session: 'pipeline', command: 'npm run lint && npm test', wait: 120000, @@ -691,6 +704,7 @@ Commands are interpreted by bash, so pipes, &&, ||, redirects, and globs all wor { params: { action: 'start', + comment: 'Testing frontend package separately', session: 'frontend-test', command: 'pnpm test', cwd: 'packages/frontend', @@ -702,6 +716,7 @@ Commands are interpreted by bash, so pipes, &&, ||, redirects, and globs all wor { params: { action: 'start', + comment: 'Starting E2E test suite', session: 'e2e-tests', command: 'npm run test:e2e', wait: 120000, @@ -711,28 +726,40 @@ Commands are interpreted by bash, so pipes, &&, ||, redirects, and globs all wor comment: 'Long-running E2E tests still running after 120s - use capture to monitor', }, { - params: { action: 'capture', session: 'npm-install', lines: 25 }, + params: { + action: 'capture', + comment: 'Checking install progress', + session: 'npm-install', + lines: 25, + }, output: 'session=npm-install lines=25\n\nadded 874 packages in 45s', comment: 'Check output from running session', }, { - params: { action: 'send', session: 'dev-server', keys: 'C-c', enter: false }, + params: { + action: 'send', + comment: 'Stopping dev server', + session: 'dev-server', + keys: 'C-c', + enter: false, + }, output: "session=dev-server status=sent\n\nSent keys to session 'dev-server': C-c", comment: 'Send Ctrl+C to stop a process', }, { - params: { action: 'kill', session: 'npm-install' }, + params: { action: 'kill', comment: 'Cleaning up completed session', session: 'npm-install' }, output: "session=npm-install status=killed\n\nSession 'npm-install' terminated", comment: 'Terminate a session', }, { - params: { action: 'list' }, + params: { action: 'list', comment: 'Checking for running sessions' }, output: 'sessions=2\n\ntest-run: npm (running)\nnpm-install: npm (running)', comment: 'List all active tmux sessions', }, { params: { action: 'start', + comment: 'Creating PR for OAuth feature', session: 'create-pr', command: "gh pr create --title 'feat(auth): add OAuth login' --body 'Implements OAuth flow'", diff --git a/src/gadgets/todo/TodoDelete.ts b/src/gadgets/todo/TodoDelete.ts index f01b4faf..22567c5a 100644 --- a/src/gadgets/todo/TodoDelete.ts +++ b/src/gadgets/todo/TodoDelete.ts @@ -11,11 +11,12 @@ export class TodoDelete extends Gadget({ Use this to remove todos that are no longer relevant. Returns the full remaining todo list.`, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), id: z.string().describe('ID of the todo to delete.'), }), examples: [ { - params: { id: '2' }, + params: { comment: 'Removing redundant task', id: '2' }, output: 'šŸ—‘ļø Deleted todo #2: "Implement the feature"\n\nšŸ“‹ Todo List\n Progress: 1/1 done, 0 in progress, 0 pending\n\nāœ… #1 [done]: Read requirements', comment: 'Delete a todo item', diff --git a/src/gadgets/todo/TodoUpsert.ts b/src/gadgets/todo/TodoUpsert.ts index ab79478e..63e255f1 100644 --- a/src/gadgets/todo/TodoUpsert.ts +++ b/src/gadgets/todo/TodoUpsert.ts @@ -111,6 +111,7 @@ Use this to plan your work at the start of a task and track progress as you go. Returns the full todo list after the operation.`, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), id: z.string().optional().describe('ID of existing todo to update. Omit to create a new todo.'), content: z .string() @@ -130,25 +131,29 @@ Returns the full todo list after the operation.`, }), examples: [ { - params: { content: 'Read and understand the Trello card requirements' }, + params: { + comment: 'Starting task - tracking requirements analysis', + content: 'Read and understand the Trello card requirements', + }, output: 'āž• Created todo #1.\n\nšŸ“‹ Todo List\n Progress: 0/1 done, 0 in progress, 1 pending\n\n⬜ #1 [pending]: Read and understand the Trello card requirements', comment: 'Create a new todo item', }, { - params: { id: '1', status: 'in_progress' }, + params: { comment: 'Beginning work on requirements', id: '1', status: 'in_progress' }, output: 'āœļø Updated todo #1.\n\nšŸ“‹ Todo List\n Progress: 0/1 done, 1 in progress, 0 pending\n\nšŸ”„ #1 [in_progress]: Read and understand the Trello card requirements', comment: 'Mark a todo as in progress', }, { - params: { id: '1', status: 'done' }, + params: { comment: 'Finished reading requirements', id: '1', status: 'done' }, output: 'āœļø Updated todo #1.\n\nšŸ“‹ Todo List\n Progress: 1/1 done, 0 in progress, 0 pending\n\nāœ… #1 [done]: Read and understand the Trello card requirements', comment: 'Mark a todo as done', }, { params: { + comment: 'Planning implementation steps', items: [ { content: 'Create feature branch' }, { content: 'Implement feature' }, diff --git a/src/gadgets/trello/AddChecklistToCard.ts b/src/gadgets/trello/AddChecklistToCard.ts index 65298941..baea4e53 100644 --- a/src/gadgets/trello/AddChecklistToCard.ts +++ b/src/gadgets/trello/AddChecklistToCard.ts @@ -8,6 +8,7 @@ export class AddChecklistToCard extends Gadget({ 'Add a checklist with items to a Trello card. Use this to create interactive checklists for acceptance criteria or implementation steps.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), cardId: z.string().describe('The Trello card ID'), checklistName: z .string() @@ -19,6 +20,7 @@ export class AddChecklistToCard extends Gadget({ examples: [ { params: { + comment: 'Adding acceptance criteria for tracking completion', cardId: 'abc123', checklistName: 'āœ… Acceptance Criteria', items: [ @@ -31,6 +33,7 @@ export class AddChecklistToCard extends Gadget({ }, { params: { + comment: 'Breaking down implementation into trackable steps', cardId: 'abc123', checklistName: 'šŸ“‹ Implementation Steps', items: [ diff --git a/src/gadgets/trello/CreateTrelloCard.ts b/src/gadgets/trello/CreateTrelloCard.ts index eee60be8..836ba008 100644 --- a/src/gadgets/trello/CreateTrelloCard.ts +++ b/src/gadgets/trello/CreateTrelloCard.ts @@ -8,6 +8,7 @@ export class CreateTrelloCard extends Gadget({ 'Create a new Trello card in a specific list. Use this to create user story cards or break down work into smaller tasks.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), listId: z.string().describe('The Trello list ID where the card should be created'), title: z .string() @@ -25,6 +26,7 @@ export class CreateTrelloCard extends Gadget({ examples: [ { params: { + comment: 'Creating user story for password reset feature', listId: 'abc123', title: 'As a user, I want to reset my password so that I can recover my account', description: @@ -34,6 +36,7 @@ export class CreateTrelloCard extends Gadget({ }, { params: { + comment: 'Breaking down validation work into separate card', listId: 'abc123', title: 'Add email validation to signup form', description: diff --git a/src/gadgets/trello/GetMyRecentActivity.ts b/src/gadgets/trello/GetMyRecentActivity.ts index 7a0f25d2..7dce582a 100644 --- a/src/gadgets/trello/GetMyRecentActivity.ts +++ b/src/gadgets/trello/GetMyRecentActivity.ts @@ -8,6 +8,7 @@ export class GetMyRecentActivity extends Gadget({ 'Get your recent Trello activity (cards created, updated, comments posted). Use this to find cards you recently worked on or to understand context when the user refers to previous work.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), limit: z .number() .int() @@ -19,11 +20,11 @@ export class GetMyRecentActivity extends Gadget({ }), examples: [ { - params: { limit: 10 }, + params: { comment: 'Finding cards I recently worked on', limit: 10 }, comment: 'Get my last 10 actions to find cards I recently created', }, { - params: { limit: 20 }, + params: { comment: 'Reviewing my recent activity for context', limit: 20 }, comment: 'Get my recent activity with default limit of 20', }, ], diff --git a/src/gadgets/trello/ListTrelloCards.ts b/src/gadgets/trello/ListTrelloCards.ts index d76e60cb..9b0d1655 100644 --- a/src/gadgets/trello/ListTrelloCards.ts +++ b/src/gadgets/trello/ListTrelloCards.ts @@ -8,11 +8,12 @@ export class ListTrelloCards extends Gadget({ 'List all cards on a Trello list. Use this to see cards you created or to find cards to update.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), listId: z.string().describe('The Trello list ID'), }), examples: [ { - params: { listId: 'abc123' }, + params: { comment: 'Looking for existing cards to update', listId: 'abc123' }, comment: 'List all cards in the STORIES list to find ones to update', }, ], diff --git a/src/gadgets/trello/PostTrelloComment.ts b/src/gadgets/trello/PostTrelloComment.ts index e7532e5a..a6337ccd 100644 --- a/src/gadgets/trello/PostTrelloComment.ts +++ b/src/gadgets/trello/PostTrelloComment.ts @@ -8,15 +8,16 @@ export class PostTrelloComment extends Gadget({ 'Post a comment to a Trello card. Use this to communicate with the user, ask questions, or provide status updates.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), cardId: z.string().describe('The Trello card ID'), - comment: z.string().describe('The comment text to post (supports markdown)'), + text: z.string().describe('The comment text to post (supports markdown)'), }), examples: [ { params: { + comment: 'Posting status update for stakeholders', cardId: 'abc123', - comment: - 'šŸ“‹ **Brief Ready for Review**\n\nI have analyzed the codebase and updated the card description.', + text: 'šŸ“‹ **Brief Ready for Review**\n\nI have analyzed the codebase and updated the card description.', }, comment: 'Post a status update to the card', }, @@ -24,7 +25,7 @@ export class PostTrelloComment extends Gadget({ }) { override async execute(params: this['params']): Promise { try { - await trelloClient.addComment(params.cardId, params.comment); + await trelloClient.addComment(params.cardId, params.text); return 'Comment posted successfully'; } catch (error) { return formatGadgetError('posting comment', error); diff --git a/src/gadgets/trello/ReadTrelloCard.ts b/src/gadgets/trello/ReadTrelloCard.ts index ee09b937..f1cb34fe 100644 --- a/src/gadgets/trello/ReadTrelloCard.ts +++ b/src/gadgets/trello/ReadTrelloCard.ts @@ -8,6 +8,7 @@ export class ReadTrelloCard extends Gadget({ 'Read a Trello card to retrieve its title, description, comments, checklists, and attachments. Use this to understand the current state of the card before making changes.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), cardId: z.string().describe('The Trello card ID'), includeComments: z .boolean() @@ -17,11 +18,19 @@ export class ReadTrelloCard extends Gadget({ }), examples: [ { - params: { cardId: 'abc123', includeComments: true }, + params: { + comment: 'Reading card to understand requirements', + cardId: 'abc123', + includeComments: true, + }, comment: 'Read the card with its comments to understand context', }, { - params: { cardId: 'abc123', includeComments: false }, + params: { + comment: 'Quick check of card title and description', + cardId: 'abc123', + includeComments: false, + }, comment: 'Read just the card title and description', }, ], diff --git a/src/gadgets/trello/UpdateChecklistItem.ts b/src/gadgets/trello/UpdateChecklistItem.ts index 0358c008..64b12d7c 100644 --- a/src/gadgets/trello/UpdateChecklistItem.ts +++ b/src/gadgets/trello/UpdateChecklistItem.ts @@ -8,6 +8,7 @@ export class UpdateChecklistItem extends Gadget({ 'Update a checklist item state on a Trello card. Use this to mark acceptance criteria as complete or incomplete.', timeoutMs: 15000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), cardId: z.string().describe('The Trello card ID'), checkItemId: z.string().describe('The checklist item ID to update'), state: z.enum(['complete', 'incomplete']).describe('The new state for the checklist item'), @@ -15,6 +16,7 @@ export class UpdateChecklistItem extends Gadget({ examples: [ { params: { + comment: 'Marking criterion as done after implementing feature', cardId: 'abc123', checkItemId: 'item456', state: 'complete', @@ -23,6 +25,7 @@ export class UpdateChecklistItem extends Gadget({ }, { params: { + comment: 'Reverting status - tests revealed issue', cardId: 'abc123', checkItemId: 'item789', state: 'incomplete', diff --git a/src/gadgets/trello/UpdateTrelloCard.ts b/src/gadgets/trello/UpdateTrelloCard.ts index c368b27b..6e3150fe 100644 --- a/src/gadgets/trello/UpdateTrelloCard.ts +++ b/src/gadgets/trello/UpdateTrelloCard.ts @@ -8,6 +8,7 @@ export class UpdateTrelloCard extends Gadget({ 'Update a Trello card title and/or description. Use this to save your analysis, brief, or plan to the card.', timeoutMs: 30000, schema: z.object({ + comment: z.string().min(1).describe('Brief rationale for this gadget call'), cardId: z.string().describe('The Trello card ID'), title: z .string() @@ -28,6 +29,7 @@ export class UpdateTrelloCard extends Gadget({ examples: [ { params: { + comment: 'Saving structured brief to card', cardId: 'abc123', description: '## Context\n\nBackground info...\n\n## Requirements\n\n- Item 1\n- Item 2', }, @@ -35,6 +37,7 @@ export class UpdateTrelloCard extends Gadget({ }, { params: { + comment: 'Updating title to be more action-oriented', cardId: 'abc123', title: 'Add user authentication flow', }, From 43b8ffbc70e9f3add08069448d6c642a7d673ba1 Mon Sep 17 00:00:00 2001 From: zbigniew sobiecki Date: Sun, 18 Jan 2026 09:56:53 +0100 Subject: [PATCH 2/2] refactor(gadgets): remove comment param from todo/trello gadgets These gadgets are self-explanatory in their actions and don't benefit from the additional rationale requirement like file/system operations do. Co-Authored-By: Claude Opus 4.5 --- src/agents/base.ts | 2 +- src/gadgets/todo/TodoDelete.ts | 3 +-- src/gadgets/todo/TodoUpsert.ts | 7 ++----- src/gadgets/trello/AddChecklistToCard.ts | 3 --- src/gadgets/trello/CreateTrelloCard.ts | 3 --- src/gadgets/trello/GetMyRecentActivity.ts | 5 ++--- src/gadgets/trello/ListTrelloCards.ts | 3 +-- src/gadgets/trello/PostTrelloComment.ts | 2 -- src/gadgets/trello/ReadTrelloCard.ts | 13 ++----------- src/gadgets/trello/UpdateChecklistItem.ts | 3 --- src/gadgets/trello/UpdateTrelloCard.ts | 3 --- 11 files changed, 9 insertions(+), 38 deletions(-) diff --git a/src/agents/base.ts b/src/agents/base.ts index 54f91df5..dc8bad31 100644 --- a/src/agents/base.ts +++ b/src/agents/base.ts @@ -370,7 +370,7 @@ async function injectSyntheticCalls( recordSyntheticInvocationId(trackingContext, 'gc_card'); builder = builder.withSyntheticGadgetCall( 'ReadTrelloCard', - { comment: 'Pre-fetching card data for task context', cardId, includeComments: true }, + { cardId, includeComments: true }, cardData, 'gc_card', ); diff --git a/src/gadgets/todo/TodoDelete.ts b/src/gadgets/todo/TodoDelete.ts index 22567c5a..f01b4faf 100644 --- a/src/gadgets/todo/TodoDelete.ts +++ b/src/gadgets/todo/TodoDelete.ts @@ -11,12 +11,11 @@ export class TodoDelete extends Gadget({ Use this to remove todos that are no longer relevant. Returns the full remaining todo list.`, schema: z.object({ - comment: z.string().min(1).describe('Brief rationale for this gadget call'), id: z.string().describe('ID of the todo to delete.'), }), examples: [ { - params: { comment: 'Removing redundant task', id: '2' }, + params: { id: '2' }, output: 'šŸ—‘ļø Deleted todo #2: "Implement the feature"\n\nšŸ“‹ Todo List\n Progress: 1/1 done, 0 in progress, 0 pending\n\nāœ… #1 [done]: Read requirements', comment: 'Delete a todo item', diff --git a/src/gadgets/todo/TodoUpsert.ts b/src/gadgets/todo/TodoUpsert.ts index 63e255f1..45a4b04b 100644 --- a/src/gadgets/todo/TodoUpsert.ts +++ b/src/gadgets/todo/TodoUpsert.ts @@ -111,7 +111,6 @@ Use this to plan your work at the start of a task and track progress as you go. Returns the full todo list after the operation.`, schema: z.object({ - comment: z.string().min(1).describe('Brief rationale for this gadget call'), id: z.string().optional().describe('ID of existing todo to update. Omit to create a new todo.'), content: z .string() @@ -132,7 +131,6 @@ Returns the full todo list after the operation.`, examples: [ { params: { - comment: 'Starting task - tracking requirements analysis', content: 'Read and understand the Trello card requirements', }, output: @@ -140,20 +138,19 @@ Returns the full todo list after the operation.`, comment: 'Create a new todo item', }, { - params: { comment: 'Beginning work on requirements', id: '1', status: 'in_progress' }, + params: { id: '1', status: 'in_progress' }, output: 'āœļø Updated todo #1.\n\nšŸ“‹ Todo List\n Progress: 0/1 done, 1 in progress, 0 pending\n\nšŸ”„ #1 [in_progress]: Read and understand the Trello card requirements', comment: 'Mark a todo as in progress', }, { - params: { comment: 'Finished reading requirements', id: '1', status: 'done' }, + params: { id: '1', status: 'done' }, output: 'āœļø Updated todo #1.\n\nšŸ“‹ Todo List\n Progress: 1/1 done, 0 in progress, 0 pending\n\nāœ… #1 [done]: Read and understand the Trello card requirements', comment: 'Mark a todo as done', }, { params: { - comment: 'Planning implementation steps', items: [ { content: 'Create feature branch' }, { content: 'Implement feature' }, diff --git a/src/gadgets/trello/AddChecklistToCard.ts b/src/gadgets/trello/AddChecklistToCard.ts index baea4e53..65298941 100644 --- a/src/gadgets/trello/AddChecklistToCard.ts +++ b/src/gadgets/trello/AddChecklistToCard.ts @@ -8,7 +8,6 @@ export class AddChecklistToCard extends Gadget({ 'Add a checklist with items to a Trello card. Use this to create interactive checklists for acceptance criteria or implementation steps.', timeoutMs: 30000, schema: z.object({ - comment: z.string().min(1).describe('Brief rationale for this gadget call'), cardId: z.string().describe('The Trello card ID'), checklistName: z .string() @@ -20,7 +19,6 @@ export class AddChecklistToCard extends Gadget({ examples: [ { params: { - comment: 'Adding acceptance criteria for tracking completion', cardId: 'abc123', checklistName: 'āœ… Acceptance Criteria', items: [ @@ -33,7 +31,6 @@ export class AddChecklistToCard extends Gadget({ }, { params: { - comment: 'Breaking down implementation into trackable steps', cardId: 'abc123', checklistName: 'šŸ“‹ Implementation Steps', items: [ diff --git a/src/gadgets/trello/CreateTrelloCard.ts b/src/gadgets/trello/CreateTrelloCard.ts index 836ba008..eee60be8 100644 --- a/src/gadgets/trello/CreateTrelloCard.ts +++ b/src/gadgets/trello/CreateTrelloCard.ts @@ -8,7 +8,6 @@ export class CreateTrelloCard extends Gadget({ 'Create a new Trello card in a specific list. Use this to create user story cards or break down work into smaller tasks.', timeoutMs: 30000, schema: z.object({ - comment: z.string().min(1).describe('Brief rationale for this gadget call'), listId: z.string().describe('The Trello list ID where the card should be created'), title: z .string() @@ -26,7 +25,6 @@ export class CreateTrelloCard extends Gadget({ examples: [ { params: { - comment: 'Creating user story for password reset feature', listId: 'abc123', title: 'As a user, I want to reset my password so that I can recover my account', description: @@ -36,7 +34,6 @@ export class CreateTrelloCard extends Gadget({ }, { params: { - comment: 'Breaking down validation work into separate card', listId: 'abc123', title: 'Add email validation to signup form', description: diff --git a/src/gadgets/trello/GetMyRecentActivity.ts b/src/gadgets/trello/GetMyRecentActivity.ts index 7dce582a..7a0f25d2 100644 --- a/src/gadgets/trello/GetMyRecentActivity.ts +++ b/src/gadgets/trello/GetMyRecentActivity.ts @@ -8,7 +8,6 @@ export class GetMyRecentActivity extends Gadget({ 'Get your recent Trello activity (cards created, updated, comments posted). Use this to find cards you recently worked on or to understand context when the user refers to previous work.', timeoutMs: 30000, schema: z.object({ - comment: z.string().min(1).describe('Brief rationale for this gadget call'), limit: z .number() .int() @@ -20,11 +19,11 @@ export class GetMyRecentActivity extends Gadget({ }), examples: [ { - params: { comment: 'Finding cards I recently worked on', limit: 10 }, + params: { limit: 10 }, comment: 'Get my last 10 actions to find cards I recently created', }, { - params: { comment: 'Reviewing my recent activity for context', limit: 20 }, + params: { limit: 20 }, comment: 'Get my recent activity with default limit of 20', }, ], diff --git a/src/gadgets/trello/ListTrelloCards.ts b/src/gadgets/trello/ListTrelloCards.ts index 9b0d1655..d76e60cb 100644 --- a/src/gadgets/trello/ListTrelloCards.ts +++ b/src/gadgets/trello/ListTrelloCards.ts @@ -8,12 +8,11 @@ export class ListTrelloCards extends Gadget({ 'List all cards on a Trello list. Use this to see cards you created or to find cards to update.', timeoutMs: 30000, schema: z.object({ - comment: z.string().min(1).describe('Brief rationale for this gadget call'), listId: z.string().describe('The Trello list ID'), }), examples: [ { - params: { comment: 'Looking for existing cards to update', listId: 'abc123' }, + params: { listId: 'abc123' }, comment: 'List all cards in the STORIES list to find ones to update', }, ], diff --git a/src/gadgets/trello/PostTrelloComment.ts b/src/gadgets/trello/PostTrelloComment.ts index a6337ccd..2e63e560 100644 --- a/src/gadgets/trello/PostTrelloComment.ts +++ b/src/gadgets/trello/PostTrelloComment.ts @@ -8,14 +8,12 @@ export class PostTrelloComment extends Gadget({ 'Post a comment to a Trello card. Use this to communicate with the user, ask questions, or provide status updates.', timeoutMs: 30000, schema: z.object({ - comment: z.string().min(1).describe('Brief rationale for this gadget call'), cardId: z.string().describe('The Trello card ID'), text: z.string().describe('The comment text to post (supports markdown)'), }), examples: [ { params: { - comment: 'Posting status update for stakeholders', cardId: 'abc123', text: 'šŸ“‹ **Brief Ready for Review**\n\nI have analyzed the codebase and updated the card description.', }, diff --git a/src/gadgets/trello/ReadTrelloCard.ts b/src/gadgets/trello/ReadTrelloCard.ts index f1cb34fe..ee09b937 100644 --- a/src/gadgets/trello/ReadTrelloCard.ts +++ b/src/gadgets/trello/ReadTrelloCard.ts @@ -8,7 +8,6 @@ export class ReadTrelloCard extends Gadget({ 'Read a Trello card to retrieve its title, description, comments, checklists, and attachments. Use this to understand the current state of the card before making changes.', timeoutMs: 30000, schema: z.object({ - comment: z.string().min(1).describe('Brief rationale for this gadget call'), cardId: z.string().describe('The Trello card ID'), includeComments: z .boolean() @@ -18,19 +17,11 @@ export class ReadTrelloCard extends Gadget({ }), examples: [ { - params: { - comment: 'Reading card to understand requirements', - cardId: 'abc123', - includeComments: true, - }, + params: { cardId: 'abc123', includeComments: true }, comment: 'Read the card with its comments to understand context', }, { - params: { - comment: 'Quick check of card title and description', - cardId: 'abc123', - includeComments: false, - }, + params: { cardId: 'abc123', includeComments: false }, comment: 'Read just the card title and description', }, ], diff --git a/src/gadgets/trello/UpdateChecklistItem.ts b/src/gadgets/trello/UpdateChecklistItem.ts index 64b12d7c..0358c008 100644 --- a/src/gadgets/trello/UpdateChecklistItem.ts +++ b/src/gadgets/trello/UpdateChecklistItem.ts @@ -8,7 +8,6 @@ export class UpdateChecklistItem extends Gadget({ 'Update a checklist item state on a Trello card. Use this to mark acceptance criteria as complete or incomplete.', timeoutMs: 15000, schema: z.object({ - comment: z.string().min(1).describe('Brief rationale for this gadget call'), cardId: z.string().describe('The Trello card ID'), checkItemId: z.string().describe('The checklist item ID to update'), state: z.enum(['complete', 'incomplete']).describe('The new state for the checklist item'), @@ -16,7 +15,6 @@ export class UpdateChecklistItem extends Gadget({ examples: [ { params: { - comment: 'Marking criterion as done after implementing feature', cardId: 'abc123', checkItemId: 'item456', state: 'complete', @@ -25,7 +23,6 @@ export class UpdateChecklistItem extends Gadget({ }, { params: { - comment: 'Reverting status - tests revealed issue', cardId: 'abc123', checkItemId: 'item789', state: 'incomplete', diff --git a/src/gadgets/trello/UpdateTrelloCard.ts b/src/gadgets/trello/UpdateTrelloCard.ts index 6e3150fe..c368b27b 100644 --- a/src/gadgets/trello/UpdateTrelloCard.ts +++ b/src/gadgets/trello/UpdateTrelloCard.ts @@ -8,7 +8,6 @@ export class UpdateTrelloCard extends Gadget({ 'Update a Trello card title and/or description. Use this to save your analysis, brief, or plan to the card.', timeoutMs: 30000, schema: z.object({ - comment: z.string().min(1).describe('Brief rationale for this gadget call'), cardId: z.string().describe('The Trello card ID'), title: z .string() @@ -29,7 +28,6 @@ export class UpdateTrelloCard extends Gadget({ examples: [ { params: { - comment: 'Saving structured brief to card', cardId: 'abc123', description: '## Context\n\nBackground info...\n\n## Requirements\n\n- Item 1\n- Item 2', }, @@ -37,7 +35,6 @@ export class UpdateTrelloCard extends Gadget({ }, { params: { - comment: 'Updating title to be more action-oriented', cardId: 'abc123', title: 'Add user authentication flow', },