Skip to content

[codex] show local freebuff model availability#542

Merged
jahooma merged 2 commits intomainfrom
jahooma/local-time-eta
Apr 25, 2026
Merged

[codex] show local freebuff model availability#542
jahooma merged 2 commits intomainfrom
jahooma/local-time-eta

Conversation

@brandonkachen
Copy link
Copy Markdown
Collaborator

Summary

  • render GLM 5.1 availability in the freebuff model picker using the user's local clock instead of a fixed ET/PT label
  • add shared helpers to compute the next open/close time for deployment-hours models across weekdays and weekends
  • add coverage for local-time labels and deployment-hour boundaries

Validation

  • bun test src/__tests__/freebuff-models.test.ts in common/
  • bun run typecheck in common/
  • bun run typecheck in cli/

@jahooma jahooma marked this pull request as ready for review April 25, 2026 00:32
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 25, 2026

Greptile Summary

This PR replaces the static '9am ET-5pm PT' deployment-hours label with a dynamic one that shows the next open or close time in the user's local timezone, backed by new shared helpers in freebuff-models.ts and a matching test suite. The component change is clean, and the tests cover the key boundary cases well. Three simplification opportunities were noted in freebuff-models.ts: a redundant minutes field alongside minute in ZonedDateParts, a stale exported constant that no longer drives the displayed label, and a loop in getNextFreebuffDeploymentStart that could be replaced with direct arithmetic.

Confidence Score: 5/5

Safe to merge; all findings are P2 style/simplification suggestions with no correctness or reliability impact.

The logic is correct, tests cover open/closed boundaries and timezone label formatting, and the component integration is straightforward. Remaining comments are purely about code clarity and the unreachable fallback branch, none of which affect runtime behavior.

common/src/constants/freebuff-models.ts — minor simplification opportunities in the interface, exported constant, and loop.

Important Files Changed

Filename Overview
common/src/constants/freebuff-models.ts Adds helpers to compute next open/close UTC instants and format them in the user's local timezone; logic is correct but has redundant minutes field, stale exported constant, and a loop that can be simplified.
cli/src/components/freebuff-model-selector.tsx Swaps the static FREEBUFF_DEPLOYMENT_HOURS_LABEL for the new dynamic getFreebuffDeploymentAvailabilityLabel call wrapped in useMemo; also contains several minor formatting cleanups with no logic issues.
common/src/tests/freebuff-models.test.ts New test file covering label formatting for open/closed states, same-day vs next-day weekday display, and ET/PT boundary checks; coverage is appropriate and assertions are correct.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: common/src/constants/freebuff-models.ts
Line: 26-34

Comment:
**Redundant `minutes` field alongside `minute` in `ZonedDateParts`**

The interface stores both `minute` (raw 0–59) and `minutes` (`hour * 60 + minute`) as similarly-named fields. `minutes` is only consumed in `isFreebuffDeploymentHours`; everywhere else the code uses `hour` and `minute` separately. Dropping `minutes` from the interface and inlining the arithmetic in `isFreebuffDeploymentHours` removes the ambiguity and one confusingly similar name:

```suggestion
interface ZonedDateParts {
  year: number
  month: number
  day: number
  weekday: string
  hour: number
  minute: number
}
```

Then in `isFreebuffDeploymentHours`:
```ts
return eastern.hour * 60 + eastern.minute >= 9 * 60 && pacific.hour * 60 + pacific.minute < 17 * 60
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: common/src/constants/freebuff-models.ts
Line: 20

Comment:
**Exported constant is now stale and no longer drives the displayed label**

`FREEBUFF_DEPLOYMENT_HOURS_LABEL` (`'9am ET-5pm PT'`) is still exported but the component now calls `getFreebuffDeploymentAvailabilityLabel` instead. Anyone importing the constant from another call site would still see the static string while the UI shows a dynamic local-time label. If this constant is no longer intended for external use, removing or deprecating it avoids silent drift; if it still needs to remain for other callers, a doc comment clarifying that it is not the UI-facing label would help.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: common/src/constants/freebuff-models.ts
Line: 176-197

Comment:
**`getNextFreebuffDeploymentStart` loop is harder to follow than necessary**

The 8-iteration loop skipping weekends and checking whether the 9 am ET candidate is still in the future can be replaced with direct arithmetic: if the current ET day is already past 9 am (or is a weekend), advance by the number of days to the next weekday, then construct the UTC instant directly. The current fallback after the loop (`offset = 8`) is also unreachable — in any 8-day window there will always be at least one weekday whose 9 am ET instant is in the future. Simplifying to at-most-a-few lines of offset arithmetic would make the intent clearer.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "show local freebuff model availability" | Re-trigger Greptile

Comment on lines +26 to +34
interface ZonedDateParts {
year: number
month: number
day: number
weekday: string
hour: number
minute: number
minutes: number
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Redundant minutes field alongside minute in ZonedDateParts

The interface stores both minute (raw 0–59) and minutes (hour * 60 + minute) as similarly-named fields. minutes is only consumed in isFreebuffDeploymentHours; everywhere else the code uses hour and minute separately. Dropping minutes from the interface and inlining the arithmetic in isFreebuffDeploymentHours removes the ambiguity and one confusingly similar name:

Suggested change
interface ZonedDateParts {
year: number
month: number
day: number
weekday: string
hour: number
minute: number
minutes: number
}
interface ZonedDateParts {
year: number
month: number
day: number
weekday: string
hour: number
minute: number
}

Then in isFreebuffDeploymentHours:

return eastern.hour * 60 + eastern.minute >= 9 * 60 && pacific.hour * 60 + pacific.minute < 17 * 60
Prompt To Fix With AI
This is a comment left during a code review.
Path: common/src/constants/freebuff-models.ts
Line: 26-34

Comment:
**Redundant `minutes` field alongside `minute` in `ZonedDateParts`**

The interface stores both `minute` (raw 0–59) and `minutes` (`hour * 60 + minute`) as similarly-named fields. `minutes` is only consumed in `isFreebuffDeploymentHours`; everywhere else the code uses `hour` and `minute` separately. Dropping `minutes` from the interface and inlining the arithmetic in `isFreebuffDeploymentHours` removes the ambiguity and one confusingly similar name:

```suggestion
interface ZonedDateParts {
  year: number
  month: number
  day: number
  weekday: string
  hour: number
  minute: number
}
```

Then in `isFreebuffDeploymentHours`:
```ts
return eastern.hour * 60 + eastern.minute >= 9 * 60 && pacific.hour * 60 + pacific.minute < 17 * 60
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in c703c2ac8. I removed minutes from ZonedDateParts and now inline the hour * 60 + minute arithmetic directly in isFreebuffDeploymentHours() so the type no longer carries the duplicate field.

@@ -20,6 +20,23 @@ export interface FreebuffModelOption {
export const FREEBUFF_DEPLOYMENT_HOURS_LABEL = '9am ET-5pm PT'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Exported constant is now stale and no longer drives the displayed label

FREEBUFF_DEPLOYMENT_HOURS_LABEL ('9am ET-5pm PT') is still exported but the component now calls getFreebuffDeploymentAvailabilityLabel instead. Anyone importing the constant from another call site would still see the static string while the UI shows a dynamic local-time label. If this constant is no longer intended for external use, removing or deprecating it avoids silent drift; if it still needs to remain for other callers, a doc comment clarifying that it is not the UI-facing label would help.

Prompt To Fix With AI
This is a comment left during a code review.
Path: common/src/constants/freebuff-models.ts
Line: 20

Comment:
**Exported constant is now stale and no longer drives the displayed label**

`FREEBUFF_DEPLOYMENT_HOURS_LABEL` (`'9am ET-5pm PT'`) is still exported but the component now calls `getFreebuffDeploymentAvailabilityLabel` instead. Anyone importing the constant from another call site would still see the static string while the UI shows a dynamic local-time label. If this constant is no longer intended for external use, removing or deprecating it avoids silent drift; if it still needs to remain for other callers, a doc comment clarifying that it is not the UI-facing label would help.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in c703c2ac8. I kept the constant because web/src/server/free-session/public-api.ts and web/src/llm-api/fireworks.ts still need a timezone-agnostic server-side message, and added a doc comment clarifying that the CLI should use getFreebuffDeploymentAvailabilityLabel() instead.

Comment on lines +176 to +197
function getNextFreebuffDeploymentStart(now: Date): Date {
const easternNow = getZonedParts(now, FREEBUFF_EASTERN_TIMEZONE)

for (let offset = 0; offset < 8; offset++) {
const day = addDaysToYmd(
easternNow.year,
easternNow.month,
easternNow.day,
offset,
)
if (isWeekend(day)) continue
const candidate = getUtcForZonedTime(day, FREEBUFF_EASTERN_TIMEZONE, 9, 0)
if (candidate.getTime() > now.getTime()) return candidate
}

return getUtcForZonedTime(
addDaysToYmd(easternNow.year, easternNow.month, easternNow.day, 8),
FREEBUFF_EASTERN_TIMEZONE,
9,
0,
)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 getNextFreebuffDeploymentStart loop is harder to follow than necessary

The 8-iteration loop skipping weekends and checking whether the 9 am ET candidate is still in the future can be replaced with direct arithmetic: if the current ET day is already past 9 am (or is a weekend), advance by the number of days to the next weekday, then construct the UTC instant directly. The current fallback after the loop (offset = 8) is also unreachable — in any 8-day window there will always be at least one weekday whose 9 am ET instant is in the future. Simplifying to at-most-a-few lines of offset arithmetic would make the intent clearer.

Prompt To Fix With AI
This is a comment left during a code review.
Path: common/src/constants/freebuff-models.ts
Line: 176-197

Comment:
**`getNextFreebuffDeploymentStart` loop is harder to follow than necessary**

The 8-iteration loop skipping weekends and checking whether the 9 am ET candidate is still in the future can be replaced with direct arithmetic: if the current ET day is already past 9 am (or is a weekend), advance by the number of days to the next weekday, then construct the UTC instant directly. The current fallback after the loop (`offset = 8`) is also unreachable — in any 8-day window there will always be at least one weekday whose 9 am ET instant is in the future. Simplifying to at-most-a-few lines of offset arithmetic would make the intent clearer.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in c703c2ac8. I replaced the loop with direct weekday-based offset arithmetic, so getNextFreebuffDeploymentStart() now computes the next ET 9am opening without the fallback scan.

Copy link
Copy Markdown
Collaborator Author

Addressed the three simplification suggestions in c703c2ac8.

Changes made:

  • removed the redundant minutes field from ZonedDateParts and inlined the arithmetic in isFreebuffDeploymentHours()
  • kept FREEBUFF_DEPLOYMENT_HOURS_LABEL, but documented it as server-facing fallback copy while the CLI uses getFreebuffDeploymentAvailabilityLabel()
  • replaced the getNextFreebuffDeploymentStart() search loop with direct weekday-based offset arithmetic

Re-ran the targeted test plus common and cli typechecks after the update.

@jahooma jahooma merged commit 862d1a9 into main Apr 25, 2026
34 checks passed
@jahooma jahooma deleted the jahooma/local-time-eta branch April 25, 2026 05:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants