1- import { spawn } from " node:child_process" ;
2- import * as fs from " node:fs" ;
3- import * as path from " node:path" ;
4- import * as vscode from " vscode" ;
5- import type { SearchOptions , SearchResult , Status } from " ./types" ;
1+ import { spawn } from ' node:child_process' ;
2+ import * as fs from ' node:fs' ;
3+ import * as path from ' node:path' ;
4+ import * as vscode from ' vscode' ;
5+ import type { SearchOptions , SearchResult , Status } from ' ./types' ;
66
7- export type { SearchOptions , SearchResult } from " ./types" ;
7+ export type { SearchOptions , SearchResult } from ' ./types' ;
88
99export class RenamifyCliService {
1010 private readonly cliPath : string ;
@@ -16,23 +16,23 @@ export class RenamifyCliService {
1616 }
1717
1818 private findCliPath ( ) : string {
19- const config = vscode . workspace . getConfiguration ( " renamify" ) ;
20- const configuredPath = config . get < string > ( " cliPath" ) ;
19+ const config = vscode . workspace . getConfiguration ( ' renamify' ) ;
20+ const configuredPath = config . get < string > ( ' cliPath' ) ;
2121
2222 if ( configuredPath && fs . existsSync ( configuredPath ) ) {
2323 return configuredPath ;
2424 }
2525
2626 // Try to find in PATH
27- const pathEnv = process . env . PATH || "" ;
27+ const pathEnv = process . env . PATH || '' ;
2828 const paths = pathEnv . split ( path . delimiter ) ;
2929
3030 for ( const p of paths ) {
31- const cliPath = path . join ( p , " renamify" ) ;
31+ const cliPath = path . join ( p , ' renamify' ) ;
3232 if ( fs . existsSync ( cliPath ) ) {
3333 return cliPath ;
3434 }
35- const cliPathExe = path . join ( p , " renamify.exe" ) ;
35+ const cliPathExe = path . join ( p , ' renamify.exe' ) ;
3636 if ( fs . existsSync ( cliPathExe ) ) {
3737 return cliPathExe ;
3838 }
@@ -41,158 +41,171 @@ export class RenamifyCliService {
4141 // Try local development path
4242 const workspaceRoot = vscode . workspace . workspaceFolders ?. [ 0 ] ?. uri . fsPath ;
4343 if ( workspaceRoot ) {
44- const devPath = path . join ( workspaceRoot , " target" , " debug" , " renamify" ) ;
44+ const devPath = path . join ( workspaceRoot , ' target' , ' debug' , ' renamify' ) ;
4545 if ( fs . existsSync ( devPath ) ) {
4646 return devPath ;
4747 }
4848 const devPathExe = path . join (
4949 workspaceRoot ,
50- " target" ,
51- " debug" ,
52- " renamify.exe"
50+ ' target' ,
51+ ' debug' ,
52+ ' renamify.exe'
5353 ) ;
5454 if ( fs . existsSync ( devPathExe ) ) {
5555 return devPathExe ;
5656 }
5757 }
5858
5959 throw new Error (
60- " Renamify CLI not found. Please install it or configure the path in settings."
60+ ' Renamify CLI not found. Please install it or configure the path in settings.'
6161 ) ;
6262 }
6363
6464 async search ( searchTerm : string , options : SearchOptions ) : Promise < Plan > {
65- const args = [ " search" , searchTerm , " --output" , " json" ] ;
65+ const args = [ ' search' , searchTerm , ' --output' , ' json' ] ;
6666
6767 if ( options . include ) {
68- args . push ( " --include" , options . include ) ;
68+ args . push ( ' --include' , options . include ) ;
6969 }
7070
7171 if ( options . exclude ) {
72- args . push ( " --exclude" , options . exclude ) ;
72+ args . push ( ' --exclude' , options . exclude ) ;
7373 }
7474
7575 if ( options . excludeMatchingLines ) {
76- args . push ( " --exclude-matching-lines" , options . excludeMatchingLines ) ;
76+ args . push ( ' --exclude-matching-lines' , options . excludeMatchingLines ) ;
7777 }
7878
7979 if ( options . caseStyles && options . caseStyles . length > 0 ) {
80- args . push ( " --only-styles" , options . caseStyles . join ( "," ) ) ;
80+ args . push ( ' --only-styles' , options . caseStyles . join ( ',' ) ) ;
8181 }
8282
83- const config = vscode . workspace . getConfiguration ( " renamify" ) ;
84- if ( ! config . get ( " respectGitignore" ) ) {
85- args . push ( "-u" ) ;
83+ const config = vscode . workspace . getConfiguration ( ' renamify' ) ;
84+ if ( ! config . get ( ' respectGitignore' ) ) {
85+ args . push ( '-u' ) ;
8686 }
8787
8888 const result = await this . runCli ( args ) ;
89- return JSON . parse ( result ) ;
89+ const parsed = JSON . parse ( result ) ;
90+ // The CLI returns a wrapper object with the plan nested inside
91+ if ( ! parsed . plan ) {
92+ throw new Error ( 'Invalid response from CLI: missing plan data' ) ;
93+ }
94+ return parsed . plan ;
9095 }
9196
9297 async createPlan (
9398 searchTerm : string ,
9499 replaceTerm : string ,
95100 options : SearchOptions & { dryRun ?: boolean }
96101 ) : Promise < Plan | SearchResult [ ] > {
97- const args = [ " plan" , searchTerm , replaceTerm , " --output" , " json" ] ;
102+ const args = [ ' plan' , searchTerm , replaceTerm , ' --output' , ' json' ] ;
98103
99104 if ( options . dryRun ) {
100- args . push ( " --dry-run" ) ;
105+ args . push ( ' --dry-run' ) ;
101106 }
102107
103108 if ( options . include ) {
104- args . push ( " --include" , options . include ) ;
109+ args . push ( ' --include' , options . include ) ;
105110 }
106111
107112 if ( options . exclude ) {
108- args . push ( " --exclude" , options . exclude ) ;
113+ args . push ( ' --exclude' , options . exclude ) ;
109114 }
110115
111116 if ( options . excludeMatchingLines ) {
112- args . push ( " --exclude-matching-lines" , options . excludeMatchingLines ) ;
117+ args . push ( ' --exclude-matching-lines' , options . excludeMatchingLines ) ;
113118 }
114119
115120 if ( options . caseStyles && options . caseStyles . length > 0 ) {
116- args . push ( " --only-styles" , options . caseStyles . join ( "," ) ) ;
121+ args . push ( ' --only-styles' , options . caseStyles . join ( ',' ) ) ;
117122 }
118123
119- const config = vscode . workspace . getConfiguration ( " renamify" ) ;
120- if ( ! config . get ( " respectGitignore" ) ) {
121- args . push ( "-u" ) ;
124+ const config = vscode . workspace . getConfiguration ( ' renamify' ) ;
125+ if ( ! config . get ( ' respectGitignore' ) ) {
126+ args . push ( '-u' ) ;
122127 }
123128
124129 const result = await this . runCli ( args ) ;
125-
126- // Always return the full Plan object, whether dry-run or not
127- return JSON . parse ( result ) ;
130+ const parsed = JSON . parse ( result ) ;
131+ // The CLI returns a wrapper object with the plan nested inside
132+ if ( ! parsed . plan ) {
133+ throw new Error ( 'Invalid response from CLI: missing plan data' ) ;
134+ }
135+ return parsed . plan ;
128136 }
129137
130138 async rename (
131139 searchTerm : string ,
132140 replaceTerm : string ,
133141 options : SearchOptions
134142 ) : Promise < { planId : string } > {
135- const args = [ " rename" , searchTerm , replaceTerm , "-y" , " --output" , " json" ] ;
143+ const args = [ ' rename' , searchTerm , replaceTerm , '-y' , ' --output' , ' json' ] ;
136144
137145 if ( options . include ) {
138- args . push ( " --include" , options . include ) ;
146+ args . push ( ' --include' , options . include ) ;
139147 }
140148
141149 if ( options . exclude ) {
142- args . push ( " --exclude" , options . exclude ) ;
150+ args . push ( ' --exclude' , options . exclude ) ;
143151 }
144152
145153 if ( options . excludeMatchingLines ) {
146- args . push ( " --exclude-matching-lines" , options . excludeMatchingLines ) ;
154+ args . push ( ' --exclude-matching-lines' , options . excludeMatchingLines ) ;
147155 }
148156
149157 if ( options . caseStyles && options . caseStyles . length > 0 ) {
150- args . push ( " --only-styles" , options . caseStyles . join ( "," ) ) ;
158+ args . push ( ' --only-styles' , options . caseStyles . join ( ',' ) ) ;
151159 }
152160
153- const config = vscode . workspace . getConfiguration ( " renamify" ) ;
154- if ( ! config . get ( " respectGitignore" ) ) {
155- args . push ( "-u" ) ;
161+ const config = vscode . workspace . getConfiguration ( ' renamify' ) ;
162+ if ( ! config . get ( ' respectGitignore' ) ) {
163+ args . push ( '-u' ) ;
156164 }
157165
158166 const result = await this . runCli ( args ) ;
159167
160168 // Parse the JSON response
161- const planData = JSON . parse ( result ) ;
162- return { planId : planData . plan_id } ;
169+ const parsed = JSON . parse ( result ) ;
170+ // Extract the plan ID from the wrapper or plan
171+ const planId = parsed . plan_id || parsed . plan ?. id ;
172+ if ( ! planId ) {
173+ throw new Error ( 'Invalid response from CLI: missing plan ID' ) ;
174+ }
175+ return { planId } ;
163176 }
164177
165178 async apply ( planId ?: string ) : Promise < void > {
166- const args = [ " apply" , " --output" , " json" ] ;
179+ const args = [ ' apply' , ' --output' , ' json' ] ;
167180
168181 if ( planId ) {
169- args . push ( " --id" , planId ) ;
182+ args . push ( ' --id' , planId ) ;
170183 }
171184
172185 await this . runCli ( args ) ;
173186 }
174187
175188 async undo ( id : string ) : Promise < void > {
176- await this . runCli ( [ " undo" , id , " --output" , " json" ] ) ;
189+ await this . runCli ( [ ' undo' , id , ' --output' , ' json' ] ) ;
177190 }
178191
179192 async redo ( id : string ) : Promise < void > {
180- await this . runCli ( [ " redo" , id , " --output" , " json" ] ) ;
193+ await this . runCli ( [ ' redo' , id , ' --output' , ' json' ] ) ;
181194 }
182195
183196 async history ( limit ?: number ) : Promise < HistoryEntry [ ] > {
184- const args = [ " history" , " --output" , " json" ] ;
197+ const args = [ ' history' , ' --output' , ' json' ] ;
185198
186199 if ( limit ) {
187- args . push ( " --limit" , limit . toString ( ) ) ;
200+ args . push ( ' --limit' , limit . toString ( ) ) ;
188201 }
189202
190203 const result = await this . runCli ( args ) ;
191204 return JSON . parse ( result ) ;
192205 }
193206
194207 async status ( ) : Promise < Status > {
195- const result = await this . runCli ( [ " status" , " --output" , " json" ] ) ;
208+ const result = await this . runCli ( [ ' status' , ' --output' , ' json' ] ) ;
196209 return JSON . parse ( result ) ;
197210 }
198211
@@ -210,18 +223,18 @@ export class RenamifyCliService {
210223 env : process . env ,
211224 } ) ;
212225
213- let stdout = "" ;
214- let stderr = "" ;
226+ let stdout = '' ;
227+ let stderr = '' ;
215228
216- proc . stdout . on ( " data" , ( data ) => {
229+ proc . stdout . on ( ' data' , ( data ) => {
217230 stdout += data . toString ( ) ;
218231 } ) ;
219232
220- proc . stderr . on ( " data" , ( data ) => {
233+ proc . stderr . on ( ' data' , ( data ) => {
221234 stderr += data . toString ( ) ;
222235 } ) ;
223236
224- proc . on ( " close" , ( code ) => {
237+ proc . on ( ' close' , ( code ) => {
225238 if ( code === 0 ) {
226239 resolve ( stdout ) ;
227240 } else {
@@ -230,7 +243,7 @@ export class RenamifyCliService {
230243 }
231244 } ) ;
232245
233- proc . on ( " error" , ( err ) => {
246+ proc . on ( ' error' , ( err ) => {
234247 reject ( err ) ;
235248 } ) ;
236249 } ) ;
0 commit comments