@@ -10,12 +10,12 @@ import {
1010 LocalGitExtractor ,
1111 VectorStorage ,
1212} from '@lytics/dev-agent-core' ;
13- import { createLogger } from '@lytics/kero' ;
1413import chalk from 'chalk' ;
1514import { Command } from 'commander' ;
1615import ora from 'ora' ;
17- import { keroLogger , logger } from '../utils/logger.js' ;
16+ import { createIndexLogger , logger } from '../utils/logger.js' ;
1817import { output , printGitStats } from '../utils/output.js' ;
18+ import { ProgressRenderer } from '../utils/progress.js' ;
1919
2020/**
2121 * Create Git indexer with centralized storage
@@ -48,49 +48,91 @@ export const gitCommand = new Command('git')
4848 . addCommand (
4949 new Command ( 'index' )
5050 . description ( 'Index git commit history for semantic search' )
51- . option ( '--limit <number>' , 'Maximum commits to index (default: 500)' , Number . parseInt , 500 )
51+ . option (
52+ '--limit <number>' ,
53+ 'Maximum commits to index (default: 500)' ,
54+ ( val ) => Number . parseInt ( val , 10 ) ,
55+ 500
56+ )
5257 . option (
5358 '--since <date>' ,
5459 'Only index commits after this date (e.g., "2024-01-01", "6 months ago")'
5560 )
5661 . option ( '-v, --verbose' , 'Verbose output' , false )
5762 . action ( async ( options ) => {
58- const spinner = ora ( 'Loading configuration ...' ) . start ( ) ;
63+ const spinner = ora ( 'Initializing git indexer ...' ) . start ( ) ;
5964
6065 // Create logger for indexing
61- const indexLogger = options . verbose
62- ? createLogger ( { level : 'debug' , format : 'pretty' } )
63- : keroLogger . child ( { command : 'git-index' } ) ;
66+ const indexLogger = createIndexLogger ( options . verbose ) ;
6467
6568 try {
66- spinner . text = 'Initializing git indexer...' ;
67-
6869 const { indexer, vectorStore } = await createGitIndexer ( ) ;
6970
70- spinner . text = 'Indexing git commits...' ;
71+ // Stop spinner and switch to section-based progress
72+ spinner . stop ( ) ;
73+
74+ // Initialize progress renderer
75+ const progressRenderer = new ProgressRenderer ( { verbose : options . verbose } ) ;
76+ progressRenderer . setSections ( [ 'Extracting Commits' , 'Embedding Commits' ] ) ;
77+
78+ const startTime = Date . now ( ) ;
79+ const extractStartTime = startTime ;
80+ let embeddingStartTime = 0 ;
81+ let inEmbeddingPhase = false ;
7182
7283 const stats = await indexer . index ( {
7384 limit : options . limit ,
7485 since : options . since ,
7586 logger : indexLogger ,
7687 onProgress : ( progress ) => {
7788 if ( progress . phase === 'storing' && progress . totalCommits > 0 ) {
89+ // Transitioning to embedding phase
90+ if ( ! inEmbeddingPhase ) {
91+ const extractDuration = ( Date . now ( ) - extractStartTime ) / 1000 ;
92+ progressRenderer . completeSection (
93+ `${ progress . totalCommits . toLocaleString ( ) } commits extracted` ,
94+ extractDuration
95+ ) ;
96+ embeddingStartTime = Date . now ( ) ;
97+ inEmbeddingPhase = true ;
98+ }
99+
100+ // Update embedding progress
78101 const pct = Math . round ( ( progress . commitsProcessed / progress . totalCommits ) * 100 ) ;
79- spinner . text = `Embedding ${ progress . commitsProcessed } /${ progress . totalCommits } commits (${ pct } %)` ;
102+ progressRenderer . updateSection (
103+ `${ progress . commitsProcessed } /${ progress . totalCommits } commits (${ pct } %)`
104+ ) ;
80105 }
81106 } ,
82107 } ) ;
83108
84- spinner . succeed ( chalk . green ( 'Git history indexed!' ) ) ;
109+ // Complete embedding section
110+ if ( inEmbeddingPhase ) {
111+ const embeddingDuration = ( Date . now ( ) - embeddingStartTime ) / 1000 ;
112+ progressRenderer . completeSection (
113+ `${ stats . commitsIndexed . toLocaleString ( ) } commits` ,
114+ embeddingDuration
115+ ) ;
116+ }
85117
86- // Display stats
87- logger . log ( '' ) ;
88- logger . log ( chalk . bold ( 'Indexing Stats:' ) ) ;
89- logger . log ( ` Commits indexed: ${ chalk . yellow ( stats . commitsIndexed ) } ` ) ;
90- logger . log ( ` Duration: ${ chalk . cyan ( stats . durationMs ) } ms` ) ;
91- logger . log ( '' ) ;
92- logger . log ( chalk . gray ( 'Now you can search with: dev git search "<query>"' ) ) ;
93- logger . log ( '' ) ;
118+ const totalDuration = ( Date . now ( ) - startTime ) / 1000 ;
119+
120+ // Finalize progress display
121+ progressRenderer . done ( ) ;
122+
123+ // Display success message
124+ output . log ( '' ) ;
125+ output . success ( `Git history indexed successfully!` ) ;
126+ output . log (
127+ ` ${ chalk . bold ( 'Indexed:' ) } ${ stats . commitsIndexed . toLocaleString ( ) } commits`
128+ ) ;
129+ output . log ( ` ${ chalk . bold ( 'Duration:' ) } ${ totalDuration . toFixed ( 1 ) } s` ) ;
130+ output . log ( '' ) ;
131+ output . log ( chalk . dim ( '💡 Next step:' ) ) ;
132+ output . log (
133+ ` ${ chalk . cyan ( 'dev git search "<query>"' ) } ${ chalk . dim ( 'Search commit history' ) } `
134+ ) ;
135+ output . log ( '' ) ;
94136
95137 await vectorStore . close ( ) ;
96138 } catch ( error ) {
@@ -111,7 +153,7 @@ export const gitCommand = new Command('git')
111153 new Command ( 'search' )
112154 . description ( 'Semantic search over git commit messages' )
113155 . argument ( '<query>' , 'Search query (e.g., "authentication bug fix")' )
114- . option ( '--limit <number>' , 'Number of results' , Number . parseInt , 10 )
156+ . option ( '--limit <number>' , 'Number of results' , ( val ) => Number . parseInt ( val , 10 ) , 10 )
115157 . option ( '--json' , 'Output as JSON' )
116158 . action ( async ( query , options ) => {
117159 const spinner = ora ( 'Loading configuration...' ) . start ( ) ;
0 commit comments