33 */
44
55import { existsSync } from "node:fs" ;
6+ import { readFile } from "node:fs/promises" ;
7+ import { join } from "node:path" ;
68import type { Command } from "commander" ;
7- import type { Decision , Trajectory } from "../../core/types.js" ;
9+ import type {
10+ Decision ,
11+ TraceConversation ,
12+ TraceRecord ,
13+ Trajectory ,
14+ } from "../../core/types.js" ;
815import { FileStorage , getSearchPaths } from "../../storage/file.js" ;
916
1017/**
@@ -44,11 +51,47 @@ async function findTrajectory(id: string): Promise<Trajectory | null> {
4451 return null ;
4552}
4653
54+ /**
55+ * Find and load the trace file for a trajectory
56+ */
57+ async function findTraceFile ( id : string ) : Promise < TraceRecord | null > {
58+ const searchPaths = getSearchPaths ( ) ;
59+
60+ for ( const searchPath of searchPaths ) {
61+ if ( ! existsSync ( searchPath ) ) {
62+ continue ;
63+ }
64+
65+ const completedDir = join ( searchPath , "completed" ) ;
66+ if ( ! existsSync ( completedDir ) ) {
67+ continue ;
68+ }
69+
70+ // Search through month directories
71+ try {
72+ const { readdirSync } = await import ( "node:fs" ) ;
73+ const months = readdirSync ( completedDir ) ;
74+ for ( const month of months ) {
75+ const tracePath = join ( completedDir , month , `${ id } .trace.json` ) ;
76+ if ( existsSync ( tracePath ) ) {
77+ const content = await readFile ( tracePath , "utf-8" ) ;
78+ return JSON . parse ( content ) as TraceRecord ;
79+ }
80+ }
81+ } catch {
82+ // Continue searching
83+ }
84+ }
85+
86+ return null ;
87+ }
88+
4789export function registerShowCommand ( program : Command ) : void {
4890 program
4991 . command ( "show <id>" )
5092 . description ( "Show trajectory details" )
5193 . option ( "-d, --decisions" , "Show decisions only" )
94+ . option ( "-t, --trace" , "Show trace information" )
5295 . action ( async ( id : string , options ) => {
5396 const trajectory = await findTrajectory ( id ) ;
5497
@@ -57,6 +100,55 @@ export function registerShowCommand(program: Command): void {
57100 throw new Error ( "Trajectory not found" ) ;
58101 }
59102
103+ if ( options . trace ) {
104+ // Show trace information
105+ console . log ( `Trace for ${ trajectory . task . title } :\n` ) ;
106+
107+ // Show embedded trace reference
108+ if ( trajectory . _trace ) {
109+ console . log ( "Trace Reference:" ) ;
110+ console . log ( ` Start Ref: ${ trajectory . _trace . startRef } ` ) ;
111+ if ( trajectory . _trace . endRef ) {
112+ console . log ( ` End Ref: ${ trajectory . _trace . endRef } ` ) ;
113+ }
114+ if ( trajectory . _trace . traceId ) {
115+ console . log ( ` Trace ID: ${ trajectory . _trace . traceId } ` ) ;
116+ }
117+ console . log ( "" ) ;
118+ }
119+
120+ // Load and display trace file
121+ const trace = await findTraceFile ( id ) ;
122+ if ( trace ) {
123+ console . log ( "Trace Details:" ) ;
124+ console . log ( ` ID: ${ trace . id } ` ) ;
125+ console . log ( ` Timestamp: ${ trace . timestamp } ` ) ;
126+ console . log ( ` Files: ${ trace . files . length } ` ) ;
127+ console . log ( "" ) ;
128+
129+ if ( trace . files . length > 0 ) {
130+ console . log ( "Modified Files:" ) ;
131+ for ( const file of trace . files ) {
132+ const rangeCount = file . conversations . reduce (
133+ ( sum : number , conv : TraceConversation ) =>
134+ sum + conv . ranges . length ,
135+ 0 ,
136+ ) ;
137+ const model =
138+ file . conversations [ 0 ] ?. contributor . model ?? "unknown" ;
139+ console . log ( ` • ${ file . path } ` ) ;
140+ console . log ( ` Ranges: ${ rangeCount } , Model: ${ model } ` ) ;
141+ }
142+ }
143+ } else if ( ! trajectory . _trace ) {
144+ console . log ( "No trace information available" ) ;
145+ console . log (
146+ "Trace is captured when starting a trajectory in a git repo" ,
147+ ) ;
148+ }
149+ return ;
150+ }
151+
60152 if ( options . decisions ) {
61153 // Show decisions only
62154 const decisions = extractDecisions ( trajectory ) ;
@@ -72,7 +164,10 @@ export function registerShowCommand(program: Command): void {
72164 console . log ( ` Chose: ${ decision . chosen } ` ) ;
73165 console . log ( ` Reasoning: ${ decision . reasoning } ` ) ;
74166 if ( decision . alternatives . length > 0 ) {
75- console . log ( ` Alternatives: ${ decision . alternatives . join ( ", " ) } ` ) ;
167+ const altStrings = decision . alternatives . map ( ( a ) =>
168+ typeof a === "string" ? a : a . option ,
169+ ) ;
170+ console . log ( ` Alternatives: ${ altStrings . join ( ", " ) } ` ) ;
76171 }
77172 console . log ( "" ) ;
78173 }
0 commit comments