@@ -30,6 +30,7 @@ import {
3030 loadModelRouterConfig ,
3131 type ModelProvider ,
3232} from '../core/models/model-router.js' ;
33+ import { launchWrapper } from '../features/sweep/pty-wrapper.js' ;
3334import { FallbackMonitor } from '../core/models/fallback-monitor.js' ;
3435
3536// __filename and __dirname are provided by esbuild banner for ESM compatibility
@@ -43,6 +44,8 @@ interface ClaudeSMConfig {
4344 defaultNotifyOnDone: boolean ;
4445 defaultWhatsApp: boolean ;
4546 defaultModelRouting: boolean ;
47+ defaultSweep: boolean ;
48+ defaultGreptile: boolean ;
4649}
4750
4851interface ClaudeConfig {
@@ -65,6 +68,8 @@ interface ClaudeConfig {
6568 useModelRouting: boolean ;
6669 forceProvider ? : ModelProvider ;
6770 useThinkingMode: boolean ;
71+ useSweep: boolean ;
72+ useGreptile: boolean ;
6873}
6974
7075const DEFAULT_SM_CONFIG : ClaudeSMConfig = {
@@ -76,6 +81,8 @@ const DEFAULT_SM_CONFIG: ClaudeSMConfig = {
7681 defaultNotifyOnDone : true ,
7782 defaultWhatsApp : false ,
7883 defaultModelRouting : false ,
84+ defaultSweep : true ,
85+ defaultGreptile : true ,
7986} ;
8087
8188function getConfigPath ( ) : string {
@@ -129,6 +136,8 @@ class ClaudeSM {
129136 sessionStartTime : Date . now ( ) ,
130137 useModelRouting : this . smConfig . defaultModelRouting ,
131138 useThinkingMode : false ,
139+ useSweep : this . smConfig . defaultSweep ,
140+ useGreptile : this . smConfig . defaultGreptile ,
132141 } ;
133142
134143 this . stackmemoryPath = this . findStackMemory ( ) ;
@@ -213,6 +222,60 @@ class ClaudeSM {
213222 return null ;
214223 }
215224
225+ private ensureGreptileMcp ( ) : void {
226+ const apiKey = process . env [ 'GREPTILE_API_KEY' ] ;
227+ const ghToken = process . env [ 'GITHUB_TOKEN' ] ;
228+
229+ if ( ! apiKey ) {
230+ console . log (
231+ chalk . gray ( ' Greptile: disabled (set GREPTILE_API_KEY in .env)' )
232+ ) ;
233+ return ;
234+ }
235+
236+ // Check if already registered
237+ try {
238+ const result = execSync ( 'claude mcp list 2>/dev/null' , {
239+ encoding : 'utf-8' ,
240+ } ) ;
241+ if ( result . includes ( 'greptile' ) ) {
242+ console . log ( chalk . gray ( ' Greptile: MCP server registered' ) ) ;
243+ return ;
244+ }
245+ } catch {
246+ // claude mcp list not available, try to add anyway
247+ }
248+
249+ // Register Greptile MCP server via HTTP transport
250+ try {
251+ const cmd = [
252+ 'claude mcp add' ,
253+ '--transport http' ,
254+ 'greptile' ,
255+ 'https://api.greptile.com/mcp' ,
256+ `--header "Authorization: Bearer ${ apiKey } "` ,
257+ ] ;
258+ if ( ghToken ) {
259+ cmd . push ( `--header "X-GitHub-Token: ${ ghToken } "` ) ;
260+ }
261+ execSync ( cmd . join ( ' ' ) , { stdio : 'ignore' } ) ;
262+ console . log ( chalk . cyan ( ' Greptile: MCP server registered' ) ) ;
263+ } catch {
264+ // Fallback: register via stdio transport with npx
265+ try {
266+ const envArgs = [ `GREPTILE_API_KEY=${ apiKey } ` ] ;
267+ if ( ghToken ) envArgs . push ( `GITHUB_TOKEN=${ ghToken } ` ) ;
268+ execSync (
269+ `claude mcp add greptile -- env ${ envArgs . join ( ' ' ) } npx greptile-mcp-server` ,
270+ { stdio : 'ignore' }
271+ ) ;
272+ console . log ( chalk . cyan ( ' Greptile: MCP server registered (stdio)' ) ) ;
273+ } catch {
274+ console . log ( chalk . gray ( ' Greptile: failed to register MCP server' ) ) ;
275+ }
276+ }
277+ }
278+
216279 private setupWorktree ( ) : string | null {
217280 if ( ! this . config . useWorktree || ! this . isGitRepo ( ) ) {
218281 return null ;
@@ -674,6 +737,18 @@ class ClaudeSM {
674737 case '--no-model-routing' :
675738 this . config . useModelRouting = false ;
676739 break ;
740+ case '--sweep' :
741+ this . config . useSweep = true ;
742+ break ;
743+ case '--no-sweep' :
744+ this . config . useSweep = false ;
745+ break ;
746+ case '--greptile' :
747+ this . config . useGreptile = true ;
748+ break ;
749+ case '--no-greptile' :
750+ this . config . useGreptile = false ;
751+ break ;
677752 default :
678753 claudeArgs . push ( arg ) ;
679754 }
@@ -856,6 +931,11 @@ class ClaudeSM {
856931 }
857932 }
858933
934+ // Ensure Greptile MCP server is registered if enabled
935+ if ( this . config . useGreptile ) {
936+ this . ensureGreptileMcp ( ) ;
937+ }
938+
859939 // Start WhatsApp services if enabled
860940 if ( this . config . useWhatsApp ) {
861941 console . log (
@@ -865,6 +945,31 @@ class ClaudeSM {
865945 }
866946
867947 console . log ( ) ;
948+
949+ // Launch via Sweep PTY wrapper if enabled
950+ if ( this . config . useSweep ) {
951+ const claudeBin = this . resolveClaudeBin ( ) ;
952+ if ( ! claudeBin ) {
953+ console . error ( chalk . red ( 'Claude CLI not found.' ) ) ;
954+ process . exit ( 1 ) ;
955+ return ;
956+ }
957+ console . log (
958+ chalk . cyan ( '[Sweep] Launching Claude with prediction bar...' )
959+ ) ;
960+ console . log ( chalk . gray ( '─' . repeat ( 42 ) ) ) ;
961+ try {
962+ await launchWrapper ( {
963+ claudeBin,
964+ claudeArgs,
965+ } ) ;
966+ } catch ( error ) {
967+ console . error ( chalk . red ( ( error as Error ) . message ) ) ;
968+ process . exit ( 1 ) ;
969+ }
970+ return ;
971+ }
972+
868973 console . log ( chalk . gray ( 'Starting Claude...' ) ) ;
869974 console . log ( chalk . gray ( '─' . repeat ( 42 ) ) ) ;
870975
@@ -1041,6 +1146,12 @@ configCmd
10411146 console . log (
10421147 ` defaultModelRouting: ${ config . defaultModelRouting ? chalk . green ( 'true' ) : chalk . gray ( 'false' ) } `
10431148 ) ;
1149+ console . log (
1150+ ` defaultSweep: ${ config . defaultSweep ? chalk . green ( 'true' ) : chalk . gray ( 'false' ) } `
1151+ ) ;
1152+ console . log (
1153+ ` defaultGreptile: ${ config . defaultGreptile ? chalk . green ( 'true' ) : chalk . gray ( 'false' ) } `
1154+ ) ;
10441155 console . log ( chalk . gray ( `\nConfig: ${ getConfigPath ( ) } ` ) ) ;
10451156 } ) ;
10461157
@@ -1062,14 +1173,16 @@ configCmd
10621173 whatsapp : 'defaultWhatsApp' ,
10631174 'model-routing' : 'defaultModelRouting' ,
10641175 modelrouting : 'defaultModelRouting' ,
1176+ sweep : 'defaultSweep' ,
1177+ greptile : 'defaultGreptile' ,
10651178 } ;
10661179
10671180 const configKey = keyMap [ key ] ;
10681181 if ( ! configKey ) {
10691182 console . log ( chalk . red ( `Unknown key: ${ key } ` ) ) ;
10701183 console . log (
10711184 chalk . gray (
1072- 'Valid keys: worktree, sandbox, chrome, tracing, remote, notify-done, whatsapp'
1185+ 'Valid keys: worktree, sandbox, chrome, tracing, remote, notify-done, whatsapp, sweep, greptile '
10731186 )
10741187 ) ;
10751188 process . exit ( 1 ) ;
@@ -1185,6 +1298,31 @@ configCmd
11851298 console . log ( chalk . green ( 'Model routing disabled by default' ) ) ;
11861299 } ) ;
11871300
1301+ configCmd
1302+ . command ( 'greptile-on' )
1303+ . description (
1304+ 'Enable Greptile AI code review by default (requires GREPTILE_API_KEY)'
1305+ )
1306+ . action ( ( ) => {
1307+ const config = loadSMConfig ( ) ;
1308+ config . defaultGreptile = true ;
1309+ saveSMConfig ( config ) ;
1310+ console . log ( chalk . green ( 'Greptile enabled by default' ) ) ;
1311+ if ( ! process . env [ 'GREPTILE_API_KEY' ] ) {
1312+ console . log ( chalk . gray ( 'Set GREPTILE_API_KEY in .env to activate' ) ) ;
1313+ }
1314+ } ) ;
1315+
1316+ configCmd
1317+ . command ( 'greptile-off' )
1318+ . description ( 'Disable Greptile AI code review by default' )
1319+ . action ( ( ) => {
1320+ const config = loadSMConfig ( ) ;
1321+ config . defaultGreptile = false ;
1322+ saveSMConfig ( config ) ;
1323+ console . log ( chalk . green ( 'Greptile disabled by default' ) ) ;
1324+ } ) ;
1325+
11881326// Main command (default action when no subcommand)
11891327program
11901328 . option ( '-w, --worktree' , 'Create isolated worktree for this instance' )
@@ -1215,6 +1353,10 @@ program
12151353 . option ( '--ollama' , 'Force Ollama provider for this session' )
12161354 . option ( '--model-routing' , 'Enable model routing' )
12171355 . option ( '--no-model-routing' , 'Disable model routing' )
1356+ . option ( '--sweep' , 'Enable Sweep next-edit predictions (PTY wrapper)' )
1357+ . option ( '--no-sweep' , 'Disable Sweep predictions' )
1358+ . option ( '--greptile' , 'Enable Greptile AI code review (MCP server)' )
1359+ . option ( '--no-greptile' , 'Disable Greptile integration' )
12181360 . helpOption ( '-h, --help' , 'Display help' )
12191361 . allowUnknownOption ( true )
12201362 . action ( async ( _options ) => {
0 commit comments