@@ -96,6 +96,7 @@ type ShortTermPhaseSignalEntry = {
9696 remHits : number ;
9797 lastLightAt ?: string ;
9898 lastRemAt ?: string ;
99+ lastRemConsideredAt ?: string ;
99100} ;
100101
101102type ShortTermPhaseSignalStore = {
@@ -831,12 +832,17 @@ function normalizePhaseSignalStore(raw: unknown, nowIso: string): ShortTermPhase
831832 typeof entry . lastRemAt === "string" && entry . lastRemAt . trim ( ) . length > 0
832833 ? entry . lastRemAt
833834 : undefined ;
835+ const lastRemConsideredAt =
836+ typeof entry . lastRemConsideredAt === "string" && entry . lastRemConsideredAt . trim ( ) . length > 0
837+ ? entry . lastRemConsideredAt
838+ : undefined ;
834839 entries [ key ] = {
835840 key,
836841 lightHits,
837842 remHits,
838843 ...( lastLightAt ? { lastLightAt } : { } ) ,
839844 ...( lastRemAt ? { lastRemAt } : { } ) ,
845+ ...( lastRemConsideredAt ? { lastRemConsideredAt } : { } ) ,
840846 } ;
841847 }
842848 return {
@@ -1222,6 +1228,53 @@ export async function recordDreamingPhaseSignals(params: {
12221228 } ) ;
12231229}
12241230
1231+ export async function recordRemConsideredPhaseSignals ( params : {
1232+ workspaceDir ?: string ;
1233+ keys : string [ ] ;
1234+ nowMs ?: number ;
1235+ } ) : Promise < void > {
1236+ const workspaceDir = params . workspaceDir ?. trim ( ) ;
1237+ if ( ! workspaceDir ) {
1238+ return ;
1239+ }
1240+ const keys = [ ...new Set ( params . keys . map ( ( key ) => key . trim ( ) ) . filter ( Boolean ) ) ] ;
1241+ if ( keys . length === 0 ) {
1242+ return ;
1243+ }
1244+ const nowMs = Number . isFinite ( params . nowMs ) ? ( params . nowMs as number ) : Date . now ( ) ;
1245+ const nowIso = new Date ( nowMs ) . toISOString ( ) ;
1246+
1247+ await withShortTermLock ( workspaceDir , async ( ) => {
1248+ const [ store , phaseSignals ] = await Promise . all ( [
1249+ readStore ( workspaceDir , nowIso ) ,
1250+ readPhaseSignalStore ( workspaceDir , nowIso ) ,
1251+ ] ) ;
1252+ const knownKeys = new Set ( Object . keys ( store . entries ) ) ;
1253+
1254+ for ( const key of keys ) {
1255+ if ( ! knownKeys . has ( key ) ) {
1256+ continue ;
1257+ }
1258+ const entry = phaseSignals . entries [ key ] ?? {
1259+ key,
1260+ lightHits : 0 ,
1261+ remHits : 0 ,
1262+ } ;
1263+ entry . lastRemConsideredAt = nowIso ;
1264+ phaseSignals . entries [ key ] = entry ;
1265+ }
1266+
1267+ for ( const [ key , entry ] of Object . entries ( phaseSignals . entries ) ) {
1268+ if ( ! knownKeys . has ( key ) || ( entry . lightHits <= 0 && entry . remHits <= 0 ) ) {
1269+ delete phaseSignals . entries [ key ] ;
1270+ }
1271+ }
1272+
1273+ phaseSignals . updatedAt = nowIso ;
1274+ await writePhaseSignalStore ( workspaceDir , phaseSignals ) ;
1275+ } ) ;
1276+ }
1277+
12251278export async function readLightStagedKeys ( params : {
12261279 workspaceDir : string ;
12271280 nowMs ?: number ;
@@ -1240,8 +1293,13 @@ export async function readLightStagedKeys(params: {
12401293 }
12411294 const lastLightMs = Date . parse ( entry . lastLightAt ?? "" ) ;
12421295 const lastRemMs = Date . parse ( entry . lastRemAt ?? "" ) ;
1296+ const lastRemConsideredMs = Date . parse ( entry . lastRemConsideredAt ?? "" ) ;
1297+ const lastConsumedMs = Math . max (
1298+ Number . isFinite ( lastRemMs ) ? lastRemMs : Number . NEGATIVE_INFINITY ,
1299+ Number . isFinite ( lastRemConsideredMs ) ? lastRemConsideredMs : Number . NEGATIVE_INFINITY ,
1300+ ) ;
12431301 const hasPendingLightSignal = Number . isFinite ( lastLightMs )
1244- ? ! Number . isFinite ( lastRemMs ) || lastLightMs > lastRemMs
1302+ ? lastLightMs > lastConsumedMs
12451303 : ! entry . lastRemAt ;
12461304 if ( hasPendingLightSignal ) {
12471305 keys . add ( key ) ;
0 commit comments