refactor(app): modularize session todo and blocker state#394
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughRefactors session composer state by extracting blockers and todo/dock responsibilities into ChangesSession State Refactor & Todo/Dock
i18n Label Update
Sequence Diagram(s)sequenceDiagram
participant Composer as Composer State
participant TodoModel as Session Todo Model
participant Dock as Todo Dock Machine
participant RAF as rAF / Timers
Composer->>TodoModel: compute snapshot (primary/fallback/composer)
TodoModel->>Dock: dispatch "snapshot" transition
Dock->>RAF: schedule animationFrame / hide timeout (if completing)
RAF->>Dock: send animationFrameElapsed / hideTimerElapsed
Dock-->>Composer: expose dock/opening/completing getters
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 👉 Get your free trial and get 200 agent minutes per Slack user (a $50 value). Review rate limit: 8/10 reviews remaining, refill in 9 minutes and 6 seconds. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces helper functions and refactors the session composer state to improve the reliability of question refetching and todo dock behavior. It adds a refetchPendingQuestions utility with retry logic and updates the todo signature calculation to ignore content changes, which prevents the dock from resetting its hide timer during terminal-only refreshes. Feedback on the refetchPendingQuestions function identifies potential issues with premature termination when questions for other sessions are returned and unnecessary delays in the retry loop, providing a suggestion to refine the loop's exit conditions.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/app/src/pages/session/composer/session-composer-state.test.ts (1)
108-131: ⚡ Quick winAdd a cross-session retry test case for refetch fallback.
Current coverage doesn’t lock behavior when
list()returns pending questions for a different session before the target session appears. That’s the key edge for this fallback path.Suggested test shape
describe("refetchPendingQuestions", () => { test("retries when the running question tool appears before the pending question is listed", async () => { @@ }) + + test("does not stop early when only another session has pending questions", async () => { + const target = question("q-target", "root") + const other = question("q-other", "other") + let attempts = 0 + const applied: Record<string, QuestionRequest[] | undefined> = {} + + await refetchPendingQuestions({ + maxAttempts: 3, + delayMs: 1, + sleep: async () => {}, + shouldContinue: () => true, + list: async () => { + attempts += 1 + if (attempts === 1) return [other] + return [target] + }, + apply(sessionID, questions) { + applied[sessionID] = questions + }, + }) + + expect(applied.root?.map((item) => item.id)).toEqual(["q-target"]) + }) })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/pages/session/composer/session-composer-state.test.ts` around lines 108 - 131, Add a new test in session-composer-state.test.ts that exercises refetchPendingQuestions when list() first returns a pending question for a different session and only later returns the target session’s pending item: mock list() to return [] or a pending for a different session on initial attempts and then return the desired pending (e.g., question("q-late","root")) on a subsequent attempt, keep maxAttempts/delayMs/sleep similar to the existing test, capture calls via the apply(sessionID, questions) handler into an applied map, and assert that refetchPendingQuestions retries (attempts count) and that applied.root contains the expected "q-late" id; reference the refetchPendingQuestions invocation and the list/apply mocks so the test locks the cross-session retry fallback behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/app/src/pages/session/composer/session-composer-state-helpers.ts`:
- Around line 22-37: The code obtains questions via input.list() then applies
grouped results without re-checking cancellation; after the await you must call
input.shouldContinue() again and abort if it returns false to avoid applying
stale results, and additionally guard before calling input.apply for each
session by checking input.shouldContinue() (or break) to prevent partial
application; update the block around QuestionRequest processing and the loop
that calls input.apply(sessionID, ...) to perform this re-check and return false
when canceled.
In `@packages/app/src/pages/session/composer/session-composer-state.ts`:
- Around line 61-64: The refetch helper is currently fetching all pending
questions via sdk.client.question.list() which can make the retry stop early if
another session has a pending question; update the list provider in the
refetchPendingQuestions call so it only returns questions for the triggering
session (use the sid passed into apply/handler) by filtering the result of
sdk.client.question.list() to q.session_id === sid (or the equivalent session
identifier field), keeping shouldContinue using questionFallbackSessionID() ===
sessionID and leaving apply(sid, qs) logic unchanged.
---
Nitpick comments:
In `@packages/app/src/pages/session/composer/session-composer-state.test.ts`:
- Around line 108-131: Add a new test in session-composer-state.test.ts that
exercises refetchPendingQuestions when list() first returns a pending question
for a different session and only later returns the target session’s pending
item: mock list() to return [] or a pending for a different session on initial
attempts and then return the desired pending (e.g., question("q-late","root"))
on a subsequent attempt, keep maxAttempts/delayMs/sleep similar to the existing
test, capture calls via the apply(sessionID, questions) handler into an applied
map, and assert that refetchPendingQuestions retries (attempts count) and that
applied.root contains the expected "q-late" id; reference the
refetchPendingQuestions invocation and the list/apply mocks so the test locks
the cross-session retry fallback behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 7f1f5e20-db94-4bfb-bc92-cad4dac67795
📒 Files selected for processing (4)
packages/app/e2e/session/session-composer-dock.spec.tspackages/app/src/pages/session/composer/session-composer-state-helpers.tspackages/app/src/pages/session/composer/session-composer-state.test.tspackages/app/src/pages/session/composer/session-composer-state.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
packages/app/src/pages/session/composer/session-composer-state.ts (1)
27-36: ⚡ Quick winConsider forwarding
completingfrom the todo model too.The refactor still tracks
completingon the model and sends it to the probe, but direct consumers ofcreateSessionComposerState()can no longer read that phase from the returned state.Suggested follow-up
return { blocked: blockers.blocked, questionRequest: blockers.questionRequest, permissionRequest: blockers.permissionRequest, permissionResponding: blockers.permissionResponding, decide: blockers.decide, todos: todo.todos, dock: todo.dock, opening: todo.opening, + completing: todo.completing, }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/pages/session/composer/session-composer-state.ts` around lines 27 - 36, The returned state from createSessionComposerState() omits the todo model's completing flag so consumers can't read that phase; update the returned object to forward the completing property from the todo model (i.e., include completing: todo.completing alongside todos, dock, opening) so both probes and direct consumers see the completing state.packages/app/src/pages/session/todos/todo-model.test.ts (1)
44-50: ⚡ Quick winAdd the missing status-diff assertion.
This test says
todoDisplaySignaturetracks status too, but it only proves content and priority changes. Acompletedvscancelledcase would pin down the status component that the renderer depends on.Suggested addition
test("tracks content, priority, and status for rendering-sensitive comparisons", () => { expect(todoDisplaySignature([todo("first", "completed", "high")])).not.toBe( todoDisplaySignature([todo("first refreshed", "completed", "high")]), ) expect(todoDisplaySignature([todo("first", "completed", "high")])).not.toBe( todoDisplaySignature([todo("first", "completed", "low")]), ) + expect(todoDisplaySignature([todo("first", "completed", "high")])).not.toBe( + todoDisplaySignature([todo("first", "cancelled", "high")]), + ) })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/pages/session/todos/todo-model.test.ts` around lines 44 - 50, The test claims todoDisplaySignature tracks status but lacks a status-change assertion; update the test inside the "tracks content, priority, and status for rendering-sensitive comparisons" block to add an assertion that a change in status produces a different signature — e.g., call todoDisplaySignature([todo("first", "completed", "high")]) and assert it is not equal to todoDisplaySignature([todo("first", "cancelled", "high")]); this ensures the status component is exercised alongside the existing content and priority checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/app/src/pages/session/blockers/use-session-blockers.ts`:
- Around line 37-56: The code drops new sessionIDs when questionRefetchInflight
is true causing missed reconciles; change the logic in the createEffect that
watches questionFallbackSessionID so that instead of returning when
questionRefetchInflight is true it enqueues the latest sessionID (e.g., store
pendingSessionID variable) and after refetchPendingQuestionsForSession completes
(in the .finally where questionRefetchInflight is set false) check for a
pendingSessionID different from the just-completed session and trigger
refetchPendingQuestionsForSession again for that pendingSessionID (clearing
pendingSessionID once scheduled); update references to questionRefetchInflight,
questionFallbackSessionID, and refetchPendingQuestionsForSession accordingly to
implement queuing and re-triggering.
---
Nitpick comments:
In `@packages/app/src/pages/session/composer/session-composer-state.ts`:
- Around line 27-36: The returned state from createSessionComposerState() omits
the todo model's completing flag so consumers can't read that phase; update the
returned object to forward the completing property from the todo model (i.e.,
include completing: todo.completing alongside todos, dock, opening) so both
probes and direct consumers see the completing state.
In `@packages/app/src/pages/session/todos/todo-model.test.ts`:
- Around line 44-50: The test claims todoDisplaySignature tracks status but
lacks a status-change assertion; update the test inside the "tracks content,
priority, and status for rendering-sensitive comparisons" block to add an
assertion that a change in status produces a different signature — e.g., call
todoDisplaySignature([todo("first", "completed", "high")]) and assert it is not
equal to todoDisplaySignature([todo("first", "cancelled", "high")]); this
ensures the status component is exercised alongside the existing content and
priority checks.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 4f169cb7-6881-4b06-9d28-c1398c2ceba4
📒 Files selected for processing (17)
packages/app/src/pages/layout/sidebar-items.tsxpackages/app/src/pages/session/blockers/question-fallback.test.tspackages/app/src/pages/session/blockers/question-fallback.tspackages/app/src/pages/session/blockers/question-reconcile.test.tspackages/app/src/pages/session/blockers/question-reconcile.tspackages/app/src/pages/session/blockers/request-tree.test.tspackages/app/src/pages/session/blockers/request-tree.tspackages/app/src/pages/session/blockers/use-session-blockers.tspackages/app/src/pages/session/composer/session-composer-state.tspackages/app/src/pages/session/session-todos.tspackages/app/src/pages/session/todos/todo-dock-machine.test.tspackages/app/src/pages/session/todos/todo-dock-machine.tspackages/app/src/pages/session/todos/todo-model.test.tspackages/app/src/pages/session/todos/todo-model.tspackages/app/src/pages/session/todos/todo-source.test.tspackages/app/src/pages/session/todos/todo-source.tspackages/app/src/pages/session/todos/use-session-todos.ts
✅ Files skipped from review due to trivial changes (1)
- packages/app/src/pages/session/todos/todo-source.test.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/app/src/pages/session/todos/todo-source.ts (1)
90-90: Consider removing the unusedselectSessionTodoSnapshotalias or renaming it to clarify dock-specific semantics.The alias points to
selectSessionTodoDockSnapshot, which intentionally filters out terminal-only parts to prevent reopening the dock. The generic name masks this behavior. While the alias is currently unused in the codebase, it remains a misleading export that could cause confusion if reused later. Either rename it toselectSessionTodoDockSnapshot(drop the alias) or explicitly document its dock-specific behavior.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/pages/session/todos/todo-source.ts` at line 90, The exported alias selectSessionTodoSnapshot simply points to selectSessionTodoDockSnapshot but masks dock-specific behavior; remove the alias export to avoid confusion or replace it with an explicit export name (export { selectSessionTodoDockSnapshot } or rename the export to selectSessionTodoDockSnapshot) and, if keeping a second name, add a clear comment documenting that it intentionally filters out terminal-only parts to prevent reopening the dock; update any imports to use selectSessionTodoDockSnapshot where needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/app/src/pages/session/todos/todo-model.ts`:
- Around line 27-32: The current todoLifecycleSignature and todoDisplaySignature
use delimiter characters (\u0000, \u0001) which can collide with todo content
and produce identical signatures; replace the delimiter-based scheme with a
structured, unambiguous encoding (e.g., map the todos to plain objects
containing only the needed fields and return a JSON.stringify of that array or
compute a stable hash of that JSON) so signatures are deterministic and cannot
be spoofed by content containing the delimiters; update both
todoLifecycleSignature (use an array of statuses) and todoDisplaySignature (use
array of {status, priority, content}) to produce the JSON/string-hash output
instead of join(...) with delimiters.
---
Nitpick comments:
In `@packages/app/src/pages/session/todos/todo-source.ts`:
- Line 90: The exported alias selectSessionTodoSnapshot simply points to
selectSessionTodoDockSnapshot but masks dock-specific behavior; remove the alias
export to avoid confusion or replace it with an explicit export name (export {
selectSessionTodoDockSnapshot } or rename the export to
selectSessionTodoDockSnapshot) and, if keeping a second name, add a clear
comment documenting that it intentionally filters out terminal-only parts to
prevent reopening the dock; update any imports to use
selectSessionTodoDockSnapshot where needed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 898e44b0-1015-44bd-89bb-b8ee3697b5b3
📒 Files selected for processing (10)
packages/app/src/pages/session/blockers/question-reconcile.tspackages/app/src/pages/session/blockers/question-refetch-runner.test.tspackages/app/src/pages/session/blockers/question-refetch-runner.tspackages/app/src/pages/session/blockers/use-session-blockers.tspackages/app/src/pages/session/session-todos.test.tspackages/app/src/pages/session/session-todos.tspackages/app/src/pages/session/todos/todo-model.tspackages/app/src/pages/session/todos/todo-source.test.tspackages/app/src/pages/session/todos/todo-source.tspackages/app/src/pages/session/todos/use-session-todos.ts
✅ Files skipped from review due to trivial changes (3)
- packages/app/src/pages/session/session-todos.test.ts
- packages/app/src/pages/session/todos/todo-source.test.ts
- packages/app/src/pages/session/todos/use-session-todos.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/app/src/pages/session/blockers/use-session-blockers.ts
There was a problem hiding this comment.
🧹 Nitpick comments (2)
packages/app/src/pages/session/composer/session-composer-state.ts (1)
27-37: ⚡ Quick winExpose
completingin the returned composer state.The model and probe both track
completing, but the returned state omits it. Adding it keeps the composer state surface aligned with the delegated todo model and avoids accidental consumer regressions.✅ Minimal fix
return { blocked: blockers.blocked, recoveringQuestion: blockers.recoveringQuestion, questionRequest: blockers.questionRequest, permissionRequest: blockers.permissionRequest, permissionResponding: blockers.permissionResponding, decide: blockers.decide, todos: todo.todos, dock: todo.dock, opening: todo.opening, + completing: todo.completing, }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/pages/session/composer/session-composer-state.ts` around lines 27 - 37, The returned composer state omits the completing flag tracked by the todo model/probe; add completing to the returned object so consumers see it (e.g., include completing: todo.completing alongside todos: todo.todos, dock: todo.dock, opening: todo.opening in the returned state).packages/app/src/pages/session/todos/todo-source.ts (1)
21-102: ⚡ Quick winExtract shared snapshot-selection flow to one helper.
selectSessionTodoDataSnapshotandselectSessionTodoDockSnapshotcurrently duplicate almost all precedence/branch logic. Consolidating this reduces policy drift risk when one path is updated later.♻️ Suggested direction
+function selectSnapshot( + input: SelectSessionTodosInput, + mode: "data" | "dock", +): TodoSnapshot { + // shared precedence logic here + // tweak only the small mode-specific defaults/overrides +} + export function selectSessionTodoDataSnapshot(input: SelectSessionTodosInput): TodoSnapshot { - // duplicated logic... + return selectSnapshot(input, "data") } export function selectSessionTodoDockSnapshot(input: SelectSessionTodosInput): TodoSnapshot { - // duplicated logic... + return selectSnapshot(input, "dock") }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/pages/session/todos/todo-source.ts` around lines 21 - 102, Both functions duplicate the same precedence/branch logic; extract that into a single helper (e.g., selectSessionTodoSnapshot) that takes SelectSessionTodosInput plus a small options object to control final fields (for example {forceDockEligible?: boolean|undefined, defaultDockEligible?: boolean, includeDockEligible?: boolean}) and returns TodoSnapshot. Move the common flow that computes primaryParts/fallbackParts, calls todoPhase, and builds the snapshot into that helper, wiring dockEligible and historicalTerminal from the phase when includeDockEligible is true (or using defaultDockEligible / forceDockEligible overrides), and preserve the final "none" fallback sessionID behavior (use input.primary.sessionID). Replace selectSessionTodoDataSnapshot and selectSessionTodoDockSnapshot to call the new helper with the appropriate options (data: includeDockEligible false; dock: includeDockEligible true with defaultDockEligible false).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/app/src/pages/session/composer/session-composer-state.ts`:
- Around line 27-37: The returned composer state omits the completing flag
tracked by the todo model/probe; add completing to the returned object so
consumers see it (e.g., include completing: todo.completing alongside todos:
todo.todos, dock: todo.dock, opening: todo.opening in the returned state).
In `@packages/app/src/pages/session/todos/todo-source.ts`:
- Around line 21-102: Both functions duplicate the same precedence/branch logic;
extract that into a single helper (e.g., selectSessionTodoSnapshot) that takes
SelectSessionTodosInput plus a small options object to control final fields (for
example {forceDockEligible?: boolean|undefined, defaultDockEligible?: boolean,
includeDockEligible?: boolean}) and returns TodoSnapshot. Move the common flow
that computes primaryParts/fallbackParts, calls todoPhase, and builds the
snapshot into that helper, wiring dockEligible and historicalTerminal from the
phase when includeDockEligible is true (or using defaultDockEligible /
forceDockEligible overrides), and preserve the final "none" fallback sessionID
behavior (use input.primary.sessionID). Replace selectSessionTodoDataSnapshot
and selectSessionTodoDockSnapshot to call the new helper with the appropriate
options (data: includeDockEligible false; dock: includeDockEligible true with
defaultDockEligible false).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: fe2ce84d-5ea9-44ec-9de4-0679dac2c204
📒 Files selected for processing (11)
packages/app/src/pages/session/blockers/question-refetch-runner.test.tspackages/app/src/pages/session/blockers/question-refetch-runner.tspackages/app/src/pages/session/blockers/use-session-blockers.tspackages/app/src/pages/session/composer/session-composer-state.tspackages/app/src/pages/session/todos/todo-dock-machine.test.tspackages/app/src/pages/session/todos/todo-dock-machine.tspackages/app/src/pages/session/todos/todo-model.test.tspackages/app/src/pages/session/todos/todo-model.tspackages/app/src/pages/session/todos/todo-source.test.tspackages/app/src/pages/session/todos/todo-source.tspackages/app/src/pages/session/todos/use-session-todos.ts
✅ Files skipped from review due to trivial changes (2)
- packages/app/src/pages/session/todos/todo-model.test.ts
- packages/app/src/pages/session/todos/todo-source.test.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- packages/app/src/pages/session/blockers/question-refetch-runner.test.ts
- packages/app/src/pages/session/blockers/question-refetch-runner.ts
- packages/app/src/pages/session/blockers/use-session-blockers.ts
- packages/app/src/pages/session/todos/todo-dock-machine.test.ts
- packages/app/src/pages/session/todos/use-session-todos.ts
Summary
todos/domain modules.blockers/modules.session-composer-state.tsdown to composer wiring and test probe reporting.todowriteparts can beat lagging backend todos, terminaltodowriteparts preserve the completing lifecycle, completed-only historical sessions do not reopen the dock, terminal content-only refreshes do not restart the hide lifecycle, session switches consume transient todo completion history, and question fallback refetch is session-scoped/cancel-safe.Patch→Edit filestool label update and zh/zht translations in this PR.Why
The original #394 patch fixed symptoms inside
session-composer-state.ts, but the real problem was that composer owned too many unrelated policies: todo source arbitration, todo lifecycle/timers, request tree selection, question fallback recovery, and permission response state. This refactor makes those policies independently reviewable and unit-testable without changing backend APIs or SDK types.Related Issue
No linked issue; found during manual regression testing.
Human Review Status
Pending. A human should make the final merge decision after reviewing the final diff and verification evidence.
Review Focus
packages/app/src/pages/session/todos/todo-source.ts: data snapshot vs dock snapshot split, especially terminal parts preserving lifecycle while historical terminal sessions stay hidden.packages/app/src/pages/session/todos/todo-dock-machine.ts: active → terminal lifecycle, terminal refresh behavior, session switch behavior, and transient active history cleanup.packages/app/src/pages/session/blockers/question-reconcile.ts: session-scoped retry, async cancellation checks, and target-session-only apply.packages/app/src/pages/session/blockers/question-refetch-runner.ts: per-session inflight tracking, disposal, and current fallback restart after session changes.packages/app/src/pages/session/blockers/use-session-blockers.tsandpackages/app/src/pages/session/todos/use-session-todos.ts: Solid wiring around the pure modules.packages/app/src/pages/session/composer/session-composer-state.ts: should now only compose domain modules and expose UI-facing state.Risk Notes
Medium UI behavior risk in the session composer dock and blocking question UI. No backend schema/API/SDK/generated/dependency changes. This still does not implement SSE replay; question fallback remains a bounded frontend recovery path.
How To Verify
Screenshots or Recordings
Not attached. The visible todo dock behavior is covered by focused e2e tests; question fallback behavior is covered by deterministic unit-level fallback/reconcile/runner coverage.
Checklist
dev, and my PR title and commit messages use Conventional Commits in EnglishMaintainer labeling request: please add appropriate type, scope, and priority labels if needed.
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Tests
Chores