@@ -13,7 +13,7 @@ import {
1313 writeFileSync ,
1414 mkdirSync ,
1515} from 'fs' ;
16- import { join , basename } from 'path' ;
16+ import { basename , join } from 'path' ;
1717import { homedir , tmpdir } from 'os' ;
1818import { globSync } from 'glob' ;
1919
@@ -825,7 +825,7 @@ export class EnhancedHandoffGenerator {
825825 }
826826
827827 /**
828- * Convert handoff to markdown
828+ * Convert handoff to markdown (verbose format)
829829 */
830830 toMarkdown ( handoff : EnhancedHandoff ) : string {
831831 const lines : string [ ] = [ ] ;
@@ -935,4 +935,91 @@ export class EnhancedHandoffGenerator {
935935
936936 return lines . join ( '\n' ) ;
937937 }
938+
939+ /**
940+ * Convert handoff to compact format (~50% smaller)
941+ * Optimized for minimal context window usage
942+ */
943+ toCompact ( handoff : EnhancedHandoff ) : string {
944+ const lines : string [ ] = [ ] ;
945+
946+ // Header: single line
947+ lines . push ( `# Handoff: ${ handoff . project } @${ handoff . branch } ` ) ;
948+
949+ // Active Work: condensed
950+ const status =
951+ handoff . activeWork . status === 'in_progress'
952+ ? 'WIP'
953+ : handoff . activeWork . status ;
954+ lines . push ( `## Work: ${ handoff . activeWork . description } [${ status } ]` ) ;
955+ if ( handoff . activeWork . keyFiles . length > 0 ) {
956+ // Use basenames only, limit to 5
957+ const files = handoff . activeWork . keyFiles
958+ . slice ( 0 , 5 )
959+ . map ( ( f ) => basename ( f ) )
960+ . join ( ', ' ) ;
961+ const progress = handoff . activeWork . progress
962+ ? ` (${ handoff . activeWork . progress . replace ( ' in current session' , '' ) } )`
963+ : '' ;
964+ lines . push ( `Files: ${ files } ${ progress } ` ) ;
965+ }
966+
967+ // Decisions: single line each with arrow notation
968+ if ( handoff . decisions . length > 0 ) {
969+ lines . push ( '' ) ;
970+ lines . push ( '## Decisions' ) ;
971+ for ( const d of handoff . decisions . slice ( 0 , 7 ) ) {
972+ // Truncate long decisions
973+ const what = d . what . length > 40 ? d . what . slice ( 0 , 37 ) + '...' : d . what ;
974+ const why = d . why ? ` → ${ d . why . slice ( 0 , 50 ) } ` : '' ;
975+ lines . push ( `- ${ what } ${ why } ` ) ;
976+ }
977+ }
978+
979+ // Blockers: terse format
980+ if ( handoff . blockers . length > 0 ) {
981+ lines . push ( '' ) ;
982+ lines . push ( '## Blockers' ) ;
983+ for ( const b of handoff . blockers ) {
984+ const status = b . status === 'open' ? '!' : '✓' ;
985+ const tried = b . attempted . length > 0 ? ` → ${ b . attempted [ 0 ] } ` : '' ;
986+ lines . push ( `${ status } ${ b . issue } ${ tried } ` ) ;
987+ }
988+ }
989+
990+ // Review Feedback: only if present, condensed
991+ if ( handoff . reviewFeedback && handoff . reviewFeedback . length > 0 ) {
992+ lines . push ( '' ) ;
993+ lines . push ( '## Feedback' ) ;
994+ for ( const r of handoff . reviewFeedback . slice ( 0 , 2 ) ) {
995+ lines . push ( `[${ r . source } ]` ) ;
996+ for ( const p of r . keyPoints . slice ( 0 , 3 ) ) {
997+ lines . push ( `- ${ p . slice ( 0 , 60 ) } ` ) ;
998+ }
999+ for ( const a of r . actionItems . slice ( 0 , 2 ) ) {
1000+ lines . push ( `→ ${ a . slice ( 0 , 60 ) } ` ) ;
1001+ }
1002+ }
1003+ }
1004+
1005+ // Next Actions: only top 3
1006+ if ( handoff . nextActions . length > 0 ) {
1007+ lines . push ( '' ) ;
1008+ lines . push ( '## Next' ) ;
1009+ for ( const a of handoff . nextActions . slice ( 0 , 3 ) ) {
1010+ lines . push ( `- ${ a . slice ( 0 , 60 ) } ` ) ;
1011+ }
1012+ }
1013+
1014+ // Skip: Architecture, Patterns (can be inferred from codebase)
1015+
1016+ // Compact footer
1017+ lines . push ( '' ) ;
1018+ lines . push ( `---` ) ;
1019+ lines . push (
1020+ `~${ handoff . estimatedTokens } tokens | ${ handoff . timestamp . split ( 'T' ) [ 0 ] } `
1021+ ) ;
1022+
1023+ return lines . join ( '\n' ) ;
1024+ }
9381025}
0 commit comments