From d87423424c343b4156595c8b9b38ea6d85ea24cf Mon Sep 17 00:00:00 2001 From: Zbigniew Sobiecki Date: Mon, 16 Feb 2026 22:27:28 +0000 Subject: [PATCH] fix: render boolean CLI params as presence flags in tool guidance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude Code agents were passing `--include-comments true` which oclif rejects as an unexpected argument, since boolean flags are presence-based (--flag or --no-flag). The tool guidance rendered them as `--flag ` giving the LLM no indication of the correct syntax. - Boolean params now render as `[--flag]` (default false/unset) or `[--no-flag]` (default true, showing how to disable) - Fixes `read-work-item --include-comments true` → UnexpectedArgsError - Add test for boolean flag with default:true rendering Co-Authored-By: Claude Opus 4.6 --- src/backends/claude-code/index.ts | 12 +++++++++++- tests/unit/backends/claude-code.test.ts | 21 +++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/backends/claude-code/index.ts b/src/backends/claude-code/index.ts index e0d0c87a..858bd395 100644 --- a/src/backends/claude-code/index.ts +++ b/src/backends/claude-code/index.ts @@ -22,7 +22,10 @@ import { CLAUDE_CODE_MODEL_IDS, DEFAULT_CLAUDE_CODE_MODEL } from './models.js'; /** * Format a single CLI parameter for tool guidance documentation. */ -function formatParam(key: string, schema: { type: string; required?: boolean }): string { +function formatParam( + key: string, + schema: { type: string; required?: boolean; default?: unknown }, +): string { if (schema.type === 'array') { // Array params use repeated flags: --item "a" --item "b" const singular = key.replace(/s$/, ''); @@ -30,6 +33,13 @@ function formatParam(key: string, schema: { type: string; required?: boolean }): ? ` --${singular} (repeatable)` : ` [--${singular} (repeatable)]`; } + if (schema.type === 'boolean') { + // Boolean flags are presence-based: --flag (true) or --no-flag (false), no value argument + if (schema.default === true) { + return ` [--no-${key}]`; + } + return ` [--${key}]`; + } return schema.required ? ` --${key} <${schema.type}>` : ` [--${key} <${schema.type}>]`; } diff --git a/tests/unit/backends/claude-code.test.ts b/tests/unit/backends/claude-code.test.ts index 1dc8c169..9637b7c2 100644 --- a/tests/unit/backends/claude-code.test.ts +++ b/tests/unit/backends/claude-code.test.ts @@ -96,7 +96,7 @@ describe('buildToolGuidance', () => { expect(guidance).toContain('### ReadWorkItem'); expect(guidance).toContain('cascade-tools pm read-work-item'); expect(guidance).toContain('--workItemId '); - expect(guidance).toContain('[--includeComments ]'); + expect(guidance).toContain('[--includeComments]'); expect(guidance).toContain('### Finish'); expect(guidance).toContain('--comment '); }); @@ -110,7 +110,24 @@ describe('buildToolGuidance', () => { it('marks optional params with brackets', () => { const guidance = buildToolGuidance(sampleTools); - expect(guidance).toContain('[--includeComments ]'); + expect(guidance).toContain('[--includeComments]'); + expect(guidance).not.toContain(''); + }); + + it('renders boolean flags with default:true as --no-flag', () => { + const tools: ToolManifest[] = [ + { + name: 'TestTool', + description: 'Test.', + cliCommand: 'cascade-tools test', + parameters: { + 'include-comments': { type: 'boolean', default: true }, + }, + }, + ]; + const guidance = buildToolGuidance(tools); + expect(guidance).toContain('[--no-include-comments]'); + expect(guidance).not.toContain(''); }); it('renders array params as repeatable flags with singular name', () => {