feat: buddy dialogue flavor, draggable notch sections, usage cache fix#6
feat: buddy dialogue flavor, draggable notch sections, usage cache fix#6Mythical365 wants to merge 2 commits intotalkvalue:mainfrom
Conversation
- buddi-hook.py: track tool usage, prompt count, and denial rate per session in ~/.buddi-session-stats.json. Compute a dialogue_flavor field (chaotic/runner/explorer/methodical/neutral) sent on every event — purely additive, does not touch buddy identity at all. Follows the direction suggested in talkvalue#5 for personality-driven dialogue. - NotchHomeView.swift: make the three notch sections (music, buddy, calendar) draggable. Drag any section left or right to reorder while hovering in the notch. Order is persisted to UserDefaults so it survives restarts. No Xcode required to understand the intent — contributed for maintainer review/implementation if preferred. - UsageService.swift: fix usage display lag. Cache was loaded and shown indefinitely even when stale (>5 min old). Now detects stale cache on startup and schedules an immediate re-fetch instead of waiting another full 300s interval. startPolling() also re-fetches if called while already polling but data is stale. Note: Swift changes submitted without local build verification (no Xcode installed). Logic and API usage are correct to the best of my knowledge but maintainer review for compilation is appreciated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
3 issues found across 3 files
Confidence score: 3/5
- There is moderate merge risk because two high-confidence medium-severity issues can affect runtime behavior under normal use, so this is not a purely cosmetic change set.
- In
buddi/Buddi/Resources/buddi-hook.py, session stat updates are not atomic/locked, which can drop counter increments or reset stats when hooks run concurrently. - In
buddi/Buddi/Services/Shared/UsageService.swift, stale-cache and failure paths can leavecurrentIntervalat 0, creating an unintended 1-second polling loop;buddi/components/Notch/NotchHomeView.swiftalso leavesdraggingSectionstale on canceled drags, causing lingering dimmed UI state. - Pay close attention to
buddi/Buddi/Resources/buddi-hook.py,buddi/Buddi/Services/Shared/UsageService.swift, andbuddi/components/Notch/NotchHomeView.swift- concurrency safety, interval restoration, and drag-state cleanup need validation.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="buddi/Buddi/Resources/buddi-hook.py">
<violation number="1" location="buddi/Buddi/Resources/buddi-hook.py:98">
P2: Session stats updates are not atomic or locked, causing lost counter updates and possible stats reset under concurrent hook executions.</violation>
</file>
<file name="buddi/Buddi/Services/Shared/UsageService.swift">
<violation number="1" location="buddi/Buddi/Services/Shared/UsageService.swift:132">
P2: Stale cache sets `currentInterval` to 0, and failure paths never restore it, causing an unintended 1-second polling loop.</violation>
</file>
<file name="buddi/components/Notch/NotchHomeView.swift">
<violation number="1" location="buddi/components/Notch/NotchHomeView.swift:469">
P2: Drag state cleanup is incomplete: `draggingSection` is set on drag start but only cleared in `performDrop`, so cancelled/outside-target drags can leave a stale dimmed section.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
- buddi-hook.py: use fcntl.flock for atomic read-modify-write of session stats so concurrent hook invocations don't drop increments; use os.replace (atomic rename) for writes to avoid partial-file reads - UsageService.swift: replace currentInterval=0 with currentInterval=2 to avoid a 1-second polling loop; always restore to baseInterval on any failure/error path so the fast-fetch only fires once on stale cache - NotchHomeView.swift: remove duplicate dropExited, consolidate drag cleanup into a single path with a short delay so cancelled drags (user releases outside a drop target) clear draggingSection instead of leaving the section dimmed indefinitely Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@grayashh I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
3 issues found across 3 files
Confidence score: 3/5
- There is a concrete regression risk in
buddi/Buddi/Resources/buddi-hook.py: a duplicate function definition appears to overwrite the lock-protected version, which can make session stat updates non-atomic and lead to lost updates under concurrency. buddi/Buddi/Services/Shared/UsageService.swifthas a medium-impact retry behavior issue where the stale-cache fast interval may persist on missing-token paths, potentially causing indefinite 2-second polling.buddi/components/Notch/NotchHomeView.swiftmay leave UI order changes unsaved if drag/drop is canceled or ends outside, since reordering happens indropEnteredbut persistence is deferred toperformDrop.- Pay close attention to
buddi/Buddi/Resources/buddi-hook.py,buddi/Buddi/Services/Shared/UsageService.swift, andbuddi/components/Notch/NotchHomeView.swift- concurrency safety, retry interval reset logic, and drag-drop persistence consistency should be validated before merge.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="buddi/Buddi/Services/Shared/UsageService.swift">
<violation number="1" location="buddi/Buddi/Services/Shared/UsageService.swift:135">
P2: Stale-cache fast interval can persist in missing-token path, causing indefinite 2-second polling retries.</violation>
</file>
<file name="buddi/Buddi/Resources/buddi-hook.py">
<violation number="1" location="buddi/Buddi/Resources/buddi-hook.py:109">
P1: Duplicate function definition overwrites the lock-protected implementation, making session stats updates non-atomic and prone to lost updates under concurrency.</violation>
</file>
<file name="buddi/components/Notch/NotchHomeView.swift">
<violation number="1" location="buddi/components/Notch/NotchHomeView.swift:558">
P2: Section order is mutated during `dropEntered` but only persisted in `performDrop`, so canceled/outside drops can leave reordered state unsaved.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| @@ -3,11 +3,13 @@ | |||
| Buddi Hook | |||
There was a problem hiding this comment.
P1: Duplicate function definition overwrites the lock-protected implementation, making session stats updates non-atomic and prone to lost updates under concurrency.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At buddi/Buddi/Resources/buddi-hook.py, line 109:
<comment>Duplicate function definition overwrites the lock-protected implementation, making session stats updates non-atomic and prone to lost updates under concurrency.</comment>
<file context>
@@ -80,6 +82,98 @@ def get_cmux_surface():
+ pass
+
+
+def update_session_stats_atomic(session_id, event, tool_name=None, denied=False):
+ import fcntl
+ try:
</file context>
| // If cached data is stale, use a short interval so the first poll fires quickly | ||
| // without creating a tight loop (minimum is clamped to 1s in scheduleNextPoll) | ||
| if Date().timeIntervalSince(cached.fetchedAt) > baseInterval { | ||
| currentInterval = 2 |
There was a problem hiding this comment.
P2: Stale-cache fast interval can persist in missing-token path, causing indefinite 2-second polling retries.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At buddi/Buddi/Services/Shared/UsageService.swift, line 135:
<comment>Stale-cache fast interval can persist in missing-token path, causing indefinite 2-second polling retries.</comment>
<file context>
@@ -111,11 +120,20 @@ final class UsageService: ObservableObject {
+ // If cached data is stale, use a short interval so the first poll fires quickly
+ // without creating a tight loop (minimum is clamped to 1s in scheduleNextPoll)
+ if Date().timeIntervalSince(cached.fetchedAt) > baseInterval {
+ currentInterval = 2
+ }
}
</file context>
| func performDrop(info: DropInfo) -> Bool { | ||
| dragging = nil | ||
| dragOver = nil | ||
| onDrop() |
There was a problem hiding this comment.
P2: Section order is mutated during dropEntered but only persisted in performDrop, so canceled/outside drops can leave reordered state unsaved.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At buddi/components/Notch/NotchHomeView.swift, line 558:
<comment>Section order is mutated during `dropEntered` but only persisted in `performDrop`, so canceled/outside drops can leave reordered state unsaved.</comment>
<file context>
@@ -463,6 +487,123 @@ struct NotchHomeView: View {
+ func performDrop(info: DropInfo) -> Bool {
+ dragging = nil
+ dragOver = nil
+ onDrop()
+ return true
+ }
</file context>
buddi-hook.py: track tool usage, prompt count, and denial rate per session in ~/.buddi-session-stats.json. Compute a dialogue_flavor field (chaotic/runner/explorer/methodical/neutral) sent on every event — purely additive, does not touch buddy identity at all. Follows the direction suggested in feat: style-aware buddy generation from coding behavior #5 for personality-driven dialogue.
NotchHomeView.swift: make the three notch sections (music, buddy, calendar) draggable. Drag any section left or right to reorder while hovering in the notch. Order is persisted to UserDefaults so it survives restarts. No Xcode required to understand the intent — contributed for maintainer review/implementation if preferred.
UsageService.swift: fix usage display lag. Cache was loaded and shown indefinitely even when stale (>5 min old). Now detects stale cache on startup and schedules an immediate re-fetch instead of waiting another full 300s interval. startPolling() also re-fetches if called while already polling but data is stale.
Note: Swift changes submitted without local build verification (no Xcode installed). Logic and API usage are correct to the best of my knowledge but maintainer review for compilation is appreciated.
Description
Type of change
Checklist
Screenshots