@@ -66,80 +66,13 @@ async function schemaAction(options) {
6666 }
6767}
6868
69- /**
70- * Read from stdin if available
71- */
72- async function readStdin ( ) {
73- // Check if stdin is a TTY (interactive terminal)
74- if ( process . stdin . isTTY ) {
75- return null ;
76- }
77-
78- return new Promise ( ( resolve , reject ) => {
79- let data = '' ;
80-
81- process . stdin . setEncoding ( 'utf8' ) ;
82-
83- process . stdin . on ( 'readable' , ( ) => {
84- let chunk ;
85- while ( ( chunk = process . stdin . read ( ) ) !== null ) {
86- data += chunk ;
87- }
88- } ) ;
89-
90- process . stdin . on ( 'end' , ( ) => {
91- resolve ( data . trim ( ) || null ) ;
92- } ) ;
93-
94- process . stdin . on ( 'error' , ( err ) => {
95- reject ( err ) ;
96- } ) ;
97- } ) ;
98- }
99-
100- /**
101- * Smart JSON parser with Windows path handling
102- */
103- function parseJsonWithPathFix ( jsonString ) {
104- try {
105- // Try normal parse first
106- return JSON . parse ( jsonString ) ;
107- } catch ( firstError ) {
108- // If parsing fails, try to fix Windows paths
109- try {
110- // Pattern: "path": "X:\..." or "path":"X:\..."
111- const fixedJson = jsonString . replace (
112- / ( " (?: p a t h | f i l e | t a r g e t | s o u r c e | d e s t | d e s t i n a t i o n ) " : \s * " ) ( [ A - Z a - z ] : [ ^ " ] + ) " / g,
113- ( match , prefix , path ) => {
114- // Convert backslashes to forward slashes (universal)
115- const fixedPath = path . replace ( / \\ / g, '/' ) ;
116- return `${ prefix } ${ fixedPath } "` ;
117- }
118- ) ;
119-
120- return JSON . parse ( fixedJson ) ;
121- } catch ( secondError ) {
122- // If still fails, throw original error with helpful message
123- const errorMsg = firstError . message ;
124- const hint = errorMsg . includes ( 'escaped character' ) || errorMsg . includes ( 'position' )
125- ? '\n\n' + chalk . yellow ( 'Hint: Windows paths in JSON need forward slashes or double backslashes:' ) +
126- '\n ' + chalk . green ( '✓ "D:/Claude_dms3/file.md"' ) +
127- '\n ' + chalk . green ( '✓ "D:\\\\Claude_dms3\\\\file.md"' ) +
128- '\n ' + chalk . red ( '✗ "D:\\Claude_dms3\\file.md"' )
129- : '' ;
130-
131- throw new Error ( errorMsg + hint ) ;
132- }
133- }
134- }
135-
13669/**
13770 * Execute a tool with given parameters
13871 */
139- async function execAction ( toolName , jsonInput , options ) {
72+ async function execAction ( toolName , options ) {
14073 if ( ! toolName ) {
14174 console . error ( chalk . red ( 'Tool name is required' ) ) ;
142- console . error ( chalk . gray ( 'Usage: ccw tool exec <tool-name> \'{"param": "value"}\' ' ) ) ;
75+ console . error ( chalk . gray ( 'Usage: ccw tool exec edit_file --path file.txt --old "old" --new "new" ' ) ) ;
14376 process . exit ( 1 ) ;
14477 }
14578
@@ -150,34 +83,22 @@ async function execAction(toolName, jsonInput, options) {
15083 process . exit ( 1 ) ;
15184 }
15285
153- // Parse JSON input (default format)
154- let params = { } ;
86+ // Build params from CLI options
87+ const params = { } ;
15588
156- if ( jsonInput ) {
157- try {
158- params = parseJsonWithPathFix ( jsonInput ) ;
159- } catch ( error ) {
160- console . error ( chalk . red ( `Invalid JSON: ${ error . message } ` ) ) ;
89+ if ( toolName === 'edit_file' ) {
90+ if ( ! options . path || ! options . old || ! options . new ) {
91+ console . error ( chalk . red ( 'edit_file requires --path, --old, and --new parameters' ) ) ;
92+ console . error ( chalk . gray ( 'Usage: ccw tool exec edit_file --path file.txt --old "old text" --new "new text"' ) ) ;
16193 process . exit ( 1 ) ;
16294 }
163- }
164-
165- // Check for stdin input (for piped commands)
166- const stdinData = await readStdin ( ) ;
167- if ( stdinData ) {
168- // If tool has an 'input' parameter, use it
169- // Otherwise, try to parse stdin as JSON and merge with params
170- if ( tool . parameters ?. properties ?. input ) {
171- params . input = stdinData ;
172- } else {
173- try {
174- const stdinJson = JSON . parse ( stdinData ) ;
175- params = { ...stdinJson , ...params } ;
176- } catch {
177- // If not JSON, store as 'input' anyway
178- params . input = stdinData ;
179- }
180- }
95+ params . path = options . path ;
96+ params . oldText = options . old ;
97+ params . newText = options . new ;
98+ } else {
99+ console . error ( chalk . red ( `Tool "${ toolName } " is not supported via CLI parameters` ) ) ;
100+ console . error ( chalk . gray ( 'Currently only edit_file is supported' ) ) ;
101+ process . exit ( 1 ) ;
181102 }
182103
183104 // Execute tool
@@ -200,7 +121,7 @@ export async function toolCommand(subcommand, args, options) {
200121 await schemaAction ( { name : args } ) ;
201122 break ;
202123 case 'exec' :
203- await execAction ( args , options . json , options ) ;
124+ await execAction ( args , options ) ;
204125 break ;
205126 default :
206127 console . log ( chalk . bold . cyan ( '\nCCW Tool System\n' ) ) ;
@@ -209,9 +130,9 @@ export async function toolCommand(subcommand, args, options) {
209130 console . log ( chalk . gray ( ' schema [name] Show tool schema (JSON)' ) ) ;
210131 console . log ( chalk . gray ( ' exec <name> Execute a tool' ) ) ;
211132 console . log ( ) ;
212- console . log ( 'Examples :' ) ;
133+ console . log ( 'Usage :' ) ;
213134 console . log ( chalk . gray ( ' ccw tool list' ) ) ;
214135 console . log ( chalk . gray ( ' ccw tool schema edit_file' ) ) ;
215- console . log ( chalk . gray ( ' ccw tool exec edit_file \'{" path":" file.txt","oldText":" old","newText":" new"}\' ' ) ) ;
136+ console . log ( chalk . gray ( ' ccw tool exec edit_file -- path file.txt --old " old text" --new " new text" ' ) ) ;
216137 }
217138}
0 commit comments