GeezerVison is showing github.com — feat(site/src): add the chat projects data layer and project dialog by f0ssel · Pull Request #30377 · coder/coder
Conversation
f0ssel
commented
Oct 5, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
- Experiment (
chat-projects). First of four stacked PRs split out of feat: add chat project folders to the sidebar #29583, which is now the sidebar on top of this stack.
- API client and React Query factories for chat projects (
chatProjects.ts, keys colocated), MockChatProject, ChatProjectIcon, the create/edit ChatProjectDialog (Formik; the caller owns the mutation), and buildAgentProjectPath.
getDefaultOrganizationId now returns undefined instead of "" when there is no default organization, so the sidebar in feat: add chat project folders to the sidebar #29583 can tell "no default organization" apart and fall back to another one. Its two existing callers already fall back either way and behave the same.
getFormHelpers accepts an optional measureLength, so the length counter can count something other than UTF-16 units. Existing callers keep the default value.length.
- Field limits count code points after trimming, matching the server, with a live counter near the limit. Save stays disabled for an edit that changes nothing once trimmed. The caller resets its mutation before opening the dialog so an old save error doesn't reappear.
Stack: this PR → #30378 → #30379 → #29583
Generated with Coder Agents on behalf of @f0ssel.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
chatgpt-codex-connector[bot] reacted with thumbs up emoji
This was referenced Oct 5, 2026
coder-agents-review[bot] reacted with rocket emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Chat: Review posted | View chat
Requested: 2026-10-05 21:18 UTC by @f0ssel
Review history
- R1 (2026-10-05): 9 reviewers, 1 Nit, 9 P3, 5 P4, COMMENT. Review
- R2 (2026-10-05): 9 reviewers, 3 Nit, 11 P3, 14 P4, COMMENT. Review
- R3 (2026-10-05): 10 reviewers, 8 Nit, 12 P3, 18 P4, COMMENT. Review
- R4 (2026-10-05): 10 reviewers, 9 Nit, 12 P3, 23 P4, COMMENT. Review
- R5 (2026-10-05): 7 reviewers, 9 Nit, 12 P3, 26 P4, COMMENT. Review
- R6 (2026-10-05): 5 reviewers, 9 Nit, 12 P3, 26 P4, APPROVE. Review
- R7 (2026-10-05): 4 reviewers, 9 Nit, 12 P3, 26 P4, APPROVE. Review
deep-review v0.13.0 | Round 7 | 5da4462..e4a2471
Last posted: Round 7, 47 findings (12 P3, 26 P4, 9 Nit), APPROVE. Review
Finding inventory
Findings
| # |
Sev |
Status |
Location |
Summary |
Round |
Reviewer |
Posted |
| CRF-1 |
P3 |
Author fixed (c69403e) |
ChatProjectDialog.tsx:25 |
Length limits counted in UTF-16 code units; server counts runes |
R1 |
Netero |
Yes |
| CRF-2 |
P3 |
Author fixed (c69403e) |
ChatProjectDialog.test.tsx:15 |
Only edit-mode submit tested; create, trim, disabled, error, select, path builder untested |
R1 |
Netero |
Yes |
| CRF-3 |
P3 |
Author fixed (c69403e) |
ChatProjectDialog.tsx:56 |
No Storybook stories for ChatProjectDialog or ChatProjectIcon |
R1 |
Netero |
Yes |
| CRF-4 |
P3 |
Author fixed (c69403e) |
chatProjects.ts:65 |
deleteChatProject does not invalidate chat entity or search caches holding project_id |
R1 |
Netero |
Yes |
| CRF-5 |
Nit |
Author fixed (c69403e) |
ChatProjectDialog.tsx:118 |
getFormHelpers called without error, so server field validations not shown on fields |
R1 |
Netero |
Yes |
| CRF-6 |
Note |
Note (body) |
chatProjects.ts:9 |
No in-PR callers of new exports; consumed by stacked PRs |
R1 |
Netero |
No |
| CRF-7 |
Note |
Note (body) |
AgentSettingsUserAgentsPage.tsx:18 |
Description says one other getDefaultOrganizationId caller; there are two, behavior unchanged |
R1 |
Netero |
No |
| CRF-8 |
P3 |
Author fixed (c69403e) |
ChatProjectIcon.tsx:18 |
Failed icon load renders an empty slot instead of the folder glyph |
R1 |
Nami |
Yes |
| CRF-9 |
P3 |
Author fixed (c69403e) |
ChatProjectDialog.tsx:160 |
Save error paragraph has no role="alert"; screen readers get no announcement |
R1 |
Nami |
Yes |
| CRF-10 |
P4 |
Author fixed (c69403e) |
ChatProjectDialog.tsx:174 |
Save enabled on untouched edit form; no-op PATCH bumps updated_at and audit log |
R1 |
Nami |
Yes |
| CRF-11 |
Note |
Dropped by orchestrator (affirmation of correct onSettled ordering, asks no change) |
chatProjects.ts:37 |
onSettled returns invalidation promise |
R1 |
Nami |
No |
| CRF-12 |
P4 |
Author fixed (c69403e, documented full replace in onSubmit doc) |
ChatProjectDialog.tsx:113 |
Edit submits all fields, rewriting untouched description (trimmed) and icon |
R1 |
Mafuuu P4, Pariston P4 |
Yes |
| CRF-13 |
Note |
Note (body) |
chatProjects.ts:16 |
chatProject returns null for readable projects the caller does not own |
R1 |
Pariston |
No |
| CRF-14 |
Note |
Note (body) |
useDashboard.ts:20 |
getDefaultOrganizationId returns undefined; sibling getDefaultOrganizationName returns "" |
R1 |
Mafuuu |
No |
| CRF-15 |
P3 |
Author fixed (c69403e) |
ChatProjectDialog.test.tsx:19 |
Reset-on-reopen behavior untested; mutation moving form state above DialogContent passes |
R1 |
Bisky |
Yes |
| CRF-16 |
Note |
Dropped by orchestrator (affirmation that the existing assertion is real, asks no change) |
ChatProjectDialog.test.tsx:44 |
Existing assertion is real |
R1 |
Bisky |
No |
| CRF-17 |
P3 |
Author fixed (c69403e) |
chatProjects.ts:15 |
chatProject doc says list is already loaded for the sidebar; false at this commit |
R1 |
Gon P2 |
Yes |
| CRF-18 |
P4 |
Author fixed (c69403e) |
ChatProjectIcon.tsx:12 |
Doc does not say expanded has no effect when an icon is set |
R1 |
Gon |
Yes |
| CRF-19 |
P4 |
Author fixed (c69403e) |
ChatProjectDialog.test.tsx:15 |
Test name and closed-then-open rerender do not state what the test checks |
R1 |
Gon Nit, Leorio P4 |
Yes |
| CRF-20 |
P3 |
Author fixed (c69403e) |
ChatProjectDialog.tsx:162 |
Save error shows only message, hiding server detail on 500s |
R1 |
Leorio |
Yes |
| CRF-21 |
P4 |
Author fixed (PR description updated) |
useDashboard.ts:20 |
PR description does not say why getDefaultOrganizationId now returns undefined |
R1 |
Leorio |
Yes |
| CRF-22 |
Note |
Dropped by orchestrator (affirmation that comments are accurate, asks no change) |
chatProjects.ts:16 |
chatProject doc comment is needed |
R1 |
Leorio |
No |
| CRF-23 |
OOS |
Out of scope (body) |
useDashboard.ts:16 |
getDefaultOrganizationName returns "" for missing default org |
R1 |
Mafuuu |
No |
| CRF-24 |
OOS |
Out of scope (body) |
coderd/chat_projects.go:286 |
Server trims name and icon but not description |
R1 |
Mafuuu, Pariston |
No |
| CRF-25 |
OOS |
Out of scope (body) |
coderd/chat_projects.go:278 |
Chat project length limits are unexported, so clients must copy them |
R1 |
Netero |
No |
| CRF-26 |
P3 |
Author fixed (eb24d35) |
ChatProjectDialog.tsx:125 |
CRF-1 fix removed live length counter and error; over-limit name disables Save silently until blur |
R2 |
Netero |
Yes |
| CRF-27 |
P4 |
Author fixed (eb24d35) |
ChatProjectDialog.tsx:127 |
Whitespace-only edit makes form dirty and sends a no-op PATCH |
R2 |
Netero |
Yes |
| CRF-28 |
P4 |
Author fixed (eb24d35) |
ChatProjectIcon.tsx:32 |
Failed-load fallback has no test or story |
R2 |
Netero |
Yes |
| CRF-29 |
P4 |
Dropped by orchestrator (FE1 forbids assertions in story play functions; screenshot gap folded into CRF-26) |
ChatProjectDialog.stories.tsx:29 |
InvalidName story asserts nothing |
R2 |
Netero |
No |
| CRF-30 |
P4 |
Author fixed (eb24d35) |
ChatProjectDialog.tsx:42 |
Description and icon validated untrimmed but submitted trimmed |
R2 |
Pariston, Mafuuu, Meruem |
Yes |
| CRF-31 |
P3 |
Author fixed (eb24d35, documented caller reset on error prop) |
ChatProjectDialog.tsx:51 |
error prop survives close; stale save error shows on reopen unless caller resets mutation |
R2 |
Meruem P3, Mafuuu Note |
Yes |
| CRF-32 |
P4 |
Author fixed (eb24d35) |
chatProjects.ts:66 |
Mutation onSettled invalidations, including the CRF-4 fix, are untested |
R2 |
Bisky |
Yes |
| CRF-33 |
P4 |
Author fixed (eb24d35) |
ChatProjectDialog.test.tsx:71 |
Emoji test passes with no limit at all; boundary not pinned |
R2 |
Bisky |
Yes |
| CRF-34 |
P4 |
Author fixed (eb24d35) |
ChatProjectDialog.tsx:40 |
Whitespace-only name untested; schema trim removable without failure |
R2 |
Bisky |
Yes |
| CRF-35 |
Note |
Dropped by orchestrator (affirmation that tests are real, asks no change) |
ChatProjectDialog.test.tsx:112 |
Reopen and Escape tests verified by mutation |
R2 |
Bisky |
No |
| CRF-36 |
P4 |
Author fixed (eb24d35) |
ChatProjectDialog.tsx:25 |
Limit constants named MaxLength and lack a pointer to the server constants they copy |
R2 |
Gon P4, Leorio P4 |
Yes |
| CRF-37 |
Nit |
Author fixed (eb24d35) |
ChatProjectDialog.tsx:29 |
Code-point comment repeats itself as an example |
R2 |
Gon P2 |
Yes |
| CRF-38 |
P4 |
Author fixed (eb24d35) |
ChatProjectDialog.tsx:53 |
onSubmit doc describes the caller's PATCH instead of what the callback receives |
R2 |
Gon P2 |
Yes |
| CRF-39 |
Nit |
Author fixed (eb24d35) |
navigation.ts:12 |
buildAgentProjectPath takes a positional string; sibling takes a named object |
R2 |
Gon |
Yes |
| CRF-40 |
Note |
Dropped by orchestrator (comment audit coverage summary, asks no change) |
ChatProjectDialog.tsx |
Comment audit coverage |
R2 |
Gon |
No |
| CRF-41 |
P4 |
Author fixed (eb24d35) |
ChatProjectDialog.stories.tsx:43 |
SaveError story shows a limit error in a shape and mode the server never produces |
R2 |
Leorio |
Yes |
| CRF-42 |
Note |
Dropped by orchestrator (affirmation that comments are useful; contradicts Gon on lines 29 and 53, recorded in round log) |
ChatProjectDialog.tsx:52 |
Comments state facts the code does not |
R2 |
Leorio |
No |
| CRF-43 |
Note |
Dropped by orchestrator (reasoning against CRF-29, folded into CRF-26) |
ChatProjectDialog.stories.tsx:29 |
InvalidName story follows FE1; screenshot shows no error |
R2 |
Nami |
No |
| CRF-44 |
P3 |
Author fixed (b5292db) |
ChatProjectDialog.tsx:58 |
Live counter counts untrimmed value; shows length error on a value Save accepts |
R3 |
Netero |
Yes |
| CRF-45 |
P4 |
Author fixed (b5292db) |
ChatProjectDialog.tsx:145 |
Icon field lacks the live counter; over-limit icon disables Save silently |
R3 |
Netero |
Yes |
| CRF-46 |
P4 |
Author fixed (b5292db) |
ChatProjectDialog.tsx:57 |
withCharacterCount copies getFormHelpers maxLength logic and hides server field errors; two branches untested; max - 30 literal copied |
R3 |
Netero, Bisky P4, Gon P4 |
Yes |
| CRF-47 |
Nit |
Author fixed (b5292db) |
ChatProjectIcon.stories.tsx:31 |
FailedImage play asserts and uses querySelector (FE1, FE10) |
R3 |
Netero |
Yes |
| CRF-48 |
Nit |
Author fixed (b5292db) |
ChatProjectDialog.test.tsx:87 |
Counter assertion uses toBeInTheDocument (FE1) |
R3 |
Netero |
Yes |
| CRF-49 |
Nit |
Author fixed (b5292db) |
chatProjects.test.ts:27 |
Test retypes chat search key literal (FE7) |
R3 |
Netero |
Yes |
| CRF-50 |
OOS |
Out of scope (body) |
site/src/utils/formUtils.ts:61 |
getFormHelpers maxLength counts UTF-16 units for every form |
R3 |
Netero |
No |
| CRF-51 |
P4 |
Author fixed (b5292db) |
ChatProjectDialog.tsx:148 |
isUnchanged compares trimmed values with raw stored project; untouched form with untrimmed description enables Save; icon comparison untested |
R3 |
Mafuuu P4, Meruem P4, Bisky P4, Pariston Note |
Yes |
| CRF-52 |
Nit |
Author fixed (b5292db) |
ChatProjectDialog.tsx:55 |
withCharacterCount comment restates countCharacters |
R3 |
Gon P2 |
Yes |
| CRF-53 |
Nit |
Author fixed (b5292db) |
ChatProjectDialog.tsx:75 |
error prop doc pads the instruction with "for example" |
R3 |
Gon P2 |
Yes |
| CRF-54 |
Nit |
Dropped by orchestrator (comment unchanged since R1 and audited as kept by Gon in R1 and R2) |
ChatProjectDialog.tsx:99 |
Radix comment wording |
R3 |
Gon P2 |
No |
| CRF-55 |
Nit |
Dropped by orchestrator (comment goes away with the FailedImage querySelector removal in CRF-47) |
ChatProjectIcon.stories.tsx:30 |
Story comment wording |
R3 |
Gon P2 |
No |
| CRF-56 |
P4 |
Author fixed (b5292db) |
ChatProjectDialog.tsx:34 |
maxCharacters also trims; name hides that required relies on it |
R3 |
Gon |
Yes |
| CRF-57 |
Note |
Note (body) |
ChatProjectDialog.tsx:39 |
Name/description show the counter wording, icon shows the schema wording, server uses a third |
R3 |
Gon, Leorio |
No |
| CRF-58 |
OOS |
Out of scope (body) |
site/src/utils/formUtils.ts:61 |
maxLength - 30 counter threshold is an unnamed literal shared by every form |
R3 |
Gon |
No |
| CRF-59 |
Note |
Dropped by orchestrator (affirmations: ging-react derived-state note, Bisky mutation-verified fixes) |
ChatProjectIcon.tsx:23 |
Affirmations |
R3 |
ging-react, Bisky |
No |
| CRF-60 |
P4 |
Author fixed (e2a8992) |
ChatProjectDialog.tsx:128 |
measureLength wiring in the dialog is untested; removing it passes all dialog tests |
R4 |
Netero |
Yes |
| CRF-61 |
P4 |
Author fixed (e2a8992) |
ChatProjectIcon.test.tsx:19 |
Fallback test passes when the fallback renders nothing |
R4 |
Netero |
Yes |
| CRF-62 |
P4 |
Dropped by orchestrator (the per-field trims are the CRF-56 fix; removing them would hide trimming inside measureLength again) |
ChatProjectDialog.tsx:45 |
.trim() on description and icon schemas changes no result |
R4 |
Netero |
No |
| CRF-63 |
Note |
Note (body) |
ChatProjectDialog.tsx:37 |
maxCharacters schema message is never displayed |
R4 |
Netero |
No |
| CRF-64 |
Note |
Note (body) |
formUtils.ts:59 |
Non-string value now measures 0 instead of skipping the counter |
R4 |
Netero |
No |
| CRF-65 |
P4 |
Author fixed (e2a8992) |
ChatProjectDialog.tsx:145 |
Icon comparison in isUnchanged still untested; icon-only edit regression passes |
R4 |
Mafuuu, Bisky |
Yes |
| CRF-66 |
P4 |
Author fixed (e2a8992) |
formUtils.ts:61 |
maxLength - 30 literal now on a line this PR rewrites, in caller-chosen units |
R4 |
Gon |
Yes |
| CRF-67 |
Nit |
Dropped by orchestrator (wording only; Leorio verified the comment's content is needed) |
ChatProjectDialog.tsx:30 |
measureLength comment opens by restating code |
R4 |
Gon P2 |
No |
| CRF-68 |
Nit |
Author fixed (e2a8992) |
formUtils.ts:18 |
measureLength option doc restates the name and omits the default |
R4 |
Gon P2, Leorio Nit |
Yes |
| CRF-69 |
Nit |
Dropped by orchestrator (pre-existing accurate comment; deleting it is unrelated cleanup) |
formUtils.ts:63 |
"Show it as an error" comment restates code |
R4 |
Gon P2 |
No |
| CRF-70 |
P4 |
Author fixed (PR description updated) |
formUtils.ts:19 |
PR description does not mention the shared getFormHelpers change |
R4 |
Leorio |
Yes |
| CRF-71 |
Note |
Dropped by orchestrator (affirmations: Bisky formUtils test, Leorio comment accuracy, Kite stored-whitespace test) |
ChatProjectDialog.test.tsx:104 |
Affirmations |
R4 |
Bisky, Leorio, Kite |
No |
| CRF-72 |
P4 |
Author fixed (2f65531) |
ChatProjectDialog.tsx:136 |
Icon field's measureLength is untested |
R5 |
Netero |
Yes |
| CRF-73 |
P4 |
Author fixed (2f65531) |
formUtils.ts:68 |
: 0 fallback for non-string value is dead; type guard checked twice |
R5 |
Netero |
Yes |
| CRF-74 |
Note |
Dropped by orchestrator (confirms CRF-64 no longer applies; asks no change) |
formUtils.ts:73 |
typeof guard restored |
R5 |
Netero |
No |
| CRF-75 |
P4 |
Author fixed (2f65531) |
formUtils.ts:36 |
lengthCounterMargin doc says "within" but the check is strict, off by one |
R5 |
Mafuuu, Leorio |
Yes |
| CRF-76 |
Note |
Dropped by orchestrator (affirmations of CRF-68 and CRF-61 fixes, ask no change) |
formUtils.ts:19 |
Fix confirmations |
R5 |
Leorio |
No |
| CRF-77 |
Note |
Note (body) |
chatProjects.ts:14 |
@public tags needed now; once the stack imports the exports they only hide future dead exports from knip |
R7 |
Netero |
No |
Contested and acknowledged
Round log
Round 1
Netero first pass: 4 P3, 1 Nit, 2 Note. No P0; proceeded to panel.
Round type: round 1, full panel. Focused (TypeScript/React frontend only). Specialists: ging-ts, ging-react, nami. Core: pariston, mafuuu. Pool: bisky (tests changed), gon, leorio (once-per-PR floor). Wildcard: razor (random from distilled set).
ging-ts, ging-react, razor: no findings.
Cross-check: Gon CRF-17 P2 downgraded to P3. Keep argument: the comment gives a false precondition as the design reason and stays false if the sidebar PR never lands. Downgrade reason: the sidebar consumer is in the declared stack (#29583), the comment's other reason (org-scoped reads) is true, and the effect is a misleading comment, not runtime behavior. Leorio's note calls the same comment useful; the disagreement is about one clause. Gon Nit and Leorio P4 on test intent merged at P4. Mafuuu and Pariston P4 on edit payload merged. CRF-9 and CRF-20 share one fix (ErrorAlert has role="alert" at Alert.tsx:95 and renders detail). CRF-1 fix split: client rune counting in scope; exporting server constants from codersdk is out of scope (CRF-25). Three affirmation Notes dropped.
Totals: 9 P3, 5 P4, 1 Nit, 3 Note (body), 3 OOS. Reviewed against 5da4462..b8bb0bc.
Round 2
Churn guard: PROCEED, 15/15 round 1 findings author fixed in c69403e (CRF-12 by documenting full replace; CRF-21 in PR description).
Round type: restructure (files added: ChatProjectDialog.stories.tsx, ChatProjectIcon.stories.tsx, chatProjects.test.ts). Full panel, focused frontend: ging-ts, ging-react, nami, pariston, mafuuu, bisky, gon, leorio. Wildcard: meruem (random).
Netero (advisory, post-panel): 1 P3, 3 P4. ging-ts, ging-react: no findings. Nami verified CRF-8/9/10 fixed.
Cross-check: CRF-29 dropped. Keep argument: InvalidName captures no error in its screenshot. Drop reason: FE1 (site/AGENTS.md:7) says play functions must not assert; the screenshot gap is the CRF-26 behavior, so it is folded there (Nami). Trim validation raised by Pariston, Mafuuu, Meruem merged at P4; Meruem's cast-based fix also closes CRF-27. CRF-31: Meruem P3 vs Mafuuu Note; kept P3 (higher wins; exported component contract undocumented). Nami and Pariston report the #29583 caller calls reset() before opening, so the stack is not affected today. Gon P2 on comment bloat at line 29 downgraded to Nit and at line 53 to P4. Keep argument: the doc at 53 states an effect the dialog does not cause. Downgrade reason: both are comment wording with no runtime effect, and Leorio rates the same comments as useful. Gon P4 and Leorio P4 on limit constants merged. Four affirmation/summary Notes dropped.
Totals new: 2 P3, 9 P4, 2 Nit. Reviewed against 5da4462..c69403e.
Round 3
Churn guard: PROCEED, 13/13 round 2 findings author fixed in eb24d35 (CRF-31 by documenting the caller reset; Meruem accepts).
Round type: fix round (commit only addresses prior findings; buildAgentProjectPath signature change was the CRF-39 fix). Panel: personas with touched findings (pariston, mafuuu, meruem, bisky, gon, leorio), specialists for changed .ts/.tsx (ging-ts, ging-react, nami). Wildcard: razor.
Netero (advisory): 1 P3, 2 P4, 3 Nit, 1 OOS. ging-ts, nami, leorio, razor: no findings.
Cross-check: Mafuuu, Meruem, Bisky P4 and Pariston Note on isUnchanged merged at P4 (higher wins; the fix is in-scope and one line). Bisky untested withCharacterCount branches and Gon max - 30 literal merged into CRF-46 (same root: the copied helper). Gon rated four comment-wording items P2: two downgraded to Nit; two dropped. Keep argument: the comments are wordier than needed. Drop/downgrade reason: wording only, no runtime effect; the Radix comment is unchanged since R1 and Gon kept it in two audits; the story comment is removed by the CRF-47 fix. Gon and Leorio Notes on two wordings merged into a body note. Mafuuu OOS duplicates CRF-24.
Totals new: 1 P3, 4 P4, 5 Nit. Reviewed against 5da4462..eb24d35.
Round 4
Churn guard: PROCEED, 10/10 round 3 findings author fixed in b5292db. The commit adds a measureLength option to the shared getFormHelpers.
Round type: fix round (commit addresses prior findings; new ChatProjectIcon.test.tsx is the CRF-47 fix). Panel: ging-ts, ging-react, nami, pariston, mafuuu, meruem, bisky, gon, leorio. Wildcard: kite.
Netero (advisory): 3 P4, 2 Note. ging-ts, ging-react, nami, pariston, meruem, kite: no findings. Pariston verified the option is smaller than changing the default because other callers pair maxLength with Yup .max().
Cross-check: CRF-62 dropped. Keep argument: two schema trims change no test result. Drop reason: they are the CRF-56 fix, and removing them makes the description and icon schema rely on the trim hidden in measureLength, which CRF-56 flagged. Mafuuu and Bisky on the icon comparison merged. Gon P2 x3 on wording: one merged with Leorio's Nit at formUtils.ts:18, one dropped (Leorio verified the comment's content), one dropped (pre-existing accurate comment). CRF-58 (OOS) now in scope as CRF-66 because the PR rewrites formUtils.ts:61.
Totals new: 5 P4, 1 Nit, 2 Note (body). Reviewed against 5da4462..b5292db.
Round 5
Churn guard: PROCEED, 6/6 round 4 findings author fixed in e2a8992 (CRF-70 in PR description).
Round type: fix round. Panel: mafuuu, bisky (CRF-65), gon, leorio (CRF-66, CRF-68, CRF-70 comment and doc changes), ging-ts, ging-react (changed .ts/.tsx). Wildcard: kite.
Netero (advisory): 2 P4; CRF-64 no longer applies (typeof guard restored). ging-ts, ging-react, bisky, gon, kite: no findings.
Cross-check: Mafuuu and Leorio converge on the lengthCounterMargin doc at P4. CRF-73 kept at P4: dead branch and a doubled guard with no test on either copy.
Totals new: 3 P4. Reviewed against 5da4462..e2a8992.
Round 6
Churn guard: PROCEED, 3/3 round 5 findings author fixed in 2f65531.
Round type: fix round. Panel: mafuuu, leorio (CRF-75), bisky (CRF-72), ging-ts (formUtils.ts). Wildcard: meruem.
Netero: no findings; CRF-72, CRF-73, CRF-75 verified (CRF-72 by mutation). All panel reviewers: no findings; Mafuuu and Bisky affirmation notes not recorded as findings.
No new findings. No open findings remain. Out-of-scope items CRF-23, CRF-24, CRF-25, CRF-50 still need a human decision. Reviewed against 5da4462..2f65531.
Round 7
Churn guard: PROCEED, no open findings. New commit e4a2471 adds @public tags for knip and switches a type import to React.ComponentProps for oxlint.
Round type: fix round. Panel: ging-ts (TS lint changes), gon, leorio (doc comments touched). Wildcard: kite.
Netero: 1 Note (CRF-77, body); knip exits 0 with the tags, oxlint and tsc clean, 12 dialog tests pass. All panel reviewers: no findings.
No new findings. No open findings remain. Out-of-scope items CRF-23, CRF-24, CRF-25, CRF-50 still need a human decision. Reviewed against 5da4462..e4a2471.
About deep-review
CRF = Coder Review Finding (P0-P4, Nit, Note)
| Reviewer |
Focus |
| Bisky |
tests |
| Chopper |
ops/errors |
| Churn-guard |
change verification |
| Ging |
language modernization |
| Gon |
naming |
| Hisoka |
edge cases |
| Killua |
perf |
| Kite |
change integrity |
| Knov |
contracts |
| Knuckle |
SQL |
| Komugi |
flake/determinism |
| Kurapika |
security |
| Law |
decomposition |
| Leorio |
docs |
| Luffy |
product |
| Mafu-san |
process |
| Mafuuu |
contracts |
| Melody |
dispatch/pairing |
| Meruem |
structural |
| Nami |
frontend |
| Netero |
mechanical checks |
| Pariston |
premise testing |
| Pen-botter |
product gaps |
| Razor |
verification |
| Robin |
duplication |
| Ryosuke |
Go arch |
| Takumi |
concurrency |
| Zoro |
shape |
🤖 Managed by Coder Agents.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR adds the chat projects API client, React Query factories, ChatProjectDialog, ChatProjectIcon, and buildAgentProjectPath, and changes getDefaultOrganizationId to return undefined. Findings: 9 P3, 5 P4, 1 Nit. The missing role="alert" and the missing error detail on the save error paragraph have one fix: render ErrorAlert in place of the <p>.
Out of scope (needs a ticket or explicit acceptance by a human):
site/src/modules/dashboard/useDashboard.ts:16: getDefaultOrganizationName returns "" when there is no default organization, so its callers cannot tell a missing organization from a real name.
coderd/chat_projects.go:286: postChatProject and patchChatProject trim name and icon but not description, so API clients and the web dialog store different values for the same input.
coderd/chat_projects.go:278: the chat project length limits are unexported Go constants, so every client copies them by hand and nothing flags a copy when the server limit changes.
Notes:
site/src/api/queries/chatProjects.ts:9: no code in this PR calls the new exports; the stacked PRs consume them.
site/src/pages/AgentsPage/AgentSettingsUserAgentsPage.tsx:18: the description says getDefaultOrganizationId has one other caller; it has two. Both keep their behavior.
site/src/api/queries/chatProjects.ts:16: chatProject(id) returns null for a project an org admin can read but does not own, because the list endpoint filters by owner.
site/src/modules/dashboard/useDashboard.ts:20: getDefaultOrganizationId now returns undefined for a missing default organization while the adjacent getDefaultOrganizationName returns "".
🤖 This review was automatically generated with Coder Agents.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Count project field limits in code points like the server, show save
errors with ErrorAlert and server field validations, disable Save for
an unchanged edit, fall back to the folder glyph when a project icon
fails to load, invalidate chat entities and searches when a project is
deleted, and add tests and stories for the dialog and icon.
coder-agents-review[bot] reacted with rocket emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All 15 findings from the previous review are fixed in c69403e. This round has 2 P3, 9 P4, and 2 Nit, most of them in the fixes: the code-point length check dropped the live counter, the dirty check and the schema compare untrimmed values, and the new tests and stories leave some fixes unpinned.
No new out-of-scope items. The three from the previous review still need a ticket or explicit acceptance by a human.
🤖 This review was automatically generated with Coder Agents.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
coder-agents-review[bot] reacted with rocket emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All 13 findings from the previous review are fixed in eb24d35. This round has 1 P3, 4 P4, and 5 Nit. Most come from the withCharacterCount counter and the isUnchanged check: each normalizes the value differently from the schema and trimValues. Deriving the trimmed value once and using it for the counter, validation, the unchanged check, and submit would fix the counter mismatch, the missing icon counter, and the unchanged-check mismatch together.
Out of scope (needs a ticket or explicit acceptance by a human):
site/src/utils/formUtils.ts:61: getFormHelpers counts maxLength in UTF-16 units, so every other form that uses it shows wrong counts for emoji and other non-BMP characters.
site/src/utils/formUtils.ts:61: the maxLength - 30 counter threshold is an unnamed literal shared by every form, so the counter distance cannot be found or changed from one place.
Notes:
site/src/pages/AgentsPage/components/ChatsSidebar/dialogs/ChatProjectDialog.tsx:39: name and description show "This cannot be longer than N characters. (count/N)", the icon shows the schema's "Icon cannot be longer than 256 characters.", and the server sends "Name must be at most 64 characters." The counter and icon fixes decide which wording survives.
🤖 This review was automatically generated with Coder Agents.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
coder-agents-review[bot] reacted with rocket emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All 10 findings from the previous review are fixed in b5292db. This round has 5 P4 and 1 Nit, mostly tests that still pass when a fix is reverted, plus documentation of the shared getFormHelpers change, which every form in site/ uses.
Out of scope (needs a ticket or explicit acceptance by a human):
site/src/utils/formUtils.ts:61: getFormHelpers still counts maxLength in UTF-16 units by default, so other forms show wrong counts for emoji and other non-BMP characters.
Notes:
site/src/pages/AgentsPage/components/ChatsSidebar/dialogs/ChatProjectDialog.tsx:37: the maxCharacters schema message is never displayed, because all three fields pass the same maxLength and measureLength to getFieldHelpers and the counter error wins. The schema test still gates Save.
site/src/utils/formUtils.ts:59: a non-string field value now measures as 0 instead of skipping the counter, so a caller with maxLength under 30 would show (0/N). No current caller does.
🤖 This review was automatically generated with Coder Agents.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Name the getFormHelpers counter margin and document measureLength.
coder-agents-review[bot] reacted with rocket emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All 6 findings from the previous review are fixed in e2a8992. This round has 3 P4: one untested option on the icon field and two small issues in the getFormHelpers change.
Out of scope (needs a ticket or explicit acceptance by a human):
site/src/utils/formUtils.ts:61: getFormHelpers still counts maxLength in UTF-16 units by default, so other forms show wrong counts for emoji and other non-BMP characters.
🤖 This review was automatically generated with Coder Agents.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
coder-agents-review[bot] reacted with rocket emoji
coder-agents-review[bot] reacted with eyes emoji
All reactions
-
🚀
1 reaction
-
👀
1 reaction
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The three findings from the previous review are fixed in 2f65531, and this round found nothing new. No findings remain open.
Out of scope (needs a ticket or explicit acceptance by a human):
site/src/modules/dashboard/useDashboard.ts:16: getDefaultOrganizationName returns "" when there is no default organization, so its callers cannot tell a missing organization from a real name.
coderd/chat_projects.go:286: the server trims name and icon but not description, so API clients and the web dialog store different values for the same input.
coderd/chat_projects.go:278: the chat project length limits are unexported Go constants, so the client copies them by hand.
site/src/utils/formUtils.ts:61: getFormHelpers counts maxLength in UTF-16 units by default, so other forms show wrong counts for emoji and other non-BMP characters.
🤖 This review was automatically generated with Coder Agents.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
coder-agents-review[bot] reacted with rocket emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The commit since the previous review (e4a2471) adds @public tags for knip and changes a type import for oxlint, with no behavior change. This round found nothing new, and no findings remain open.
Out of scope (needs a ticket or explicit acceptance by a human):
site/src/modules/dashboard/useDashboard.ts:16: getDefaultOrganizationName returns "" when there is no default organization, so its callers cannot tell a missing organization from a real name.
coderd/chat_projects.go:286: the server trims name and icon but not description, so API clients and the web dialog store different values for the same input.
coderd/chat_projects.go:278: the chat project length limits are unexported Go constants, so the client copies them by hand.
site/src/utils/formUtils.ts:61: getFormHelpers counts maxLength in UTF-16 units by default, so other forms show wrong counts for emoji and other non-BMP characters.
Notes:
site/src/api/queries/chatProjects.ts:14: the @public tags on chatProjects and ChatProjectFormValues are needed while only the stacked PRs use them. After #29583 imports them, the tags would stop knip from reporting the exports if those imports are later removed, so the stack can drop them once they have callers.
🤖 This review was automatically generated with Coder Agents.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Oct 6, 2026
This was referenced Oct 6, 2026
…RecordUpdatedAt in chat store test
main is red after #30167 and #29888 landed together: the new automation
names test omits the now-required chatRecordUpdatedAt option. Same fix as
#30393; the identical hunk merges cleanly once that lands.
… project is deleted
Deleting a project invalidated every query under the chat entities family,
which refetched each open chat's loaded message pages, ACL, prompts, debug
runs, and diffs. Only the chat entities carry project_id, so invalidate
those alone.
Save was disabled only by the caller's isSubmitting, which turns on after
Formik's async validation, so a double-click sent two saves (and would
create two projects). The dialog now also waits on its own pending submit,
and awaits a promise returned by onSubmit.
…to f0ssel/chat-projects-ui-data
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Codex Review Summary
This comment shows the latest Codex review activity on this pull request.
| Review |
Status |
Commit |
Review trigger |
| 📝 Code Review |
✅ Completed 2026-10-06T09:20:08.968076Z |
53223be |
Manual request |
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review" or "@codex security review".
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee19de5e75
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…nd icon checks into stories
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 58abf36f28
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…the project dialog open while a save is pending
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4120aef426
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
… the API field error check into a story
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2a247452f5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…rt submit outcomes instead of field DOM state
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Codex Review: Didn't find any major issues. More of your lovely PRs please.
Reviewed commit: 53223be41b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Reviewers
jaaydenh
jaaydenh approved these changes
+1 more reviewer
Reviewers whose approvals may not affect merge requirements
Uh oh!
There was an error while loading. Please reload this page.
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|