Skip to content

revert #3012#3017

Merged
dimaMachina merged 2 commits intomainfrom
revert-use-callback-use-memo
Apr 5, 2026
Merged

revert #3012#3017
dimaMachina merged 2 commits intomainfrom
revert-use-callback-use-memo

Conversation

@dimaMachina
Copy link
Copy Markdown
Collaborator

No description provided.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 5, 2026

🦋 Changeset detected

Latest commit: 004b05d

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agents-api Ready Ready Preview, Comment Apr 5, 2026 0:57am
agents-docs Ready Ready Preview, Comment Apr 5, 2026 0:57am
agents-manage-ui Ready Ready Preview, Comment Apr 5, 2026 0:57am

Request Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 5, 2026

Preview URLs

Use these stable preview aliases for testing this PR:

These point to the same Vercel preview deployment as the bot comment, but they stay stable and easier to find.

Raw Vercel deployment URLs

@dimaMachina dimaMachina marked this pull request as ready for review April 5, 2026 01:33
@dimaMachina dimaMachina added this pull request to the merge queue Apr 5, 2026
@pullfrog
Copy link
Copy Markdown
Contributor

pullfrog bot commented Apr 5, 2026

TL;DR — Reverts PR #3012 (which itself reverted #1474), restoring the original removal of manual useMemo and useCallback calls across the frontend. The codebase again relies on the React Compiler for automatic memoization instead of hand-written hooks.

Key changes

  • Restore useMemo/useCallback removal from Remove useMemo and useCallback usages #1474 — Re-applies the original cleanup that replaced ~100 useMemo call sites with plain expressions or IIFEs and converted useCallback wrappers to regular functions across agents-manage-ui, agents-docs, and agents-cli.
  • Re-remove unused JsonSchemaStateData export — Drops the type export from json-schema.ts that was re-introduced by the revert.
  • Restore CSS custom property pattern — Reverts chart.tsx and sonner.tsx back to plain string keys with @ts-expect-error instead of the as string cast pattern.

Summary | 108 files | 2 commits | base: mainrevert-use-callback-use-memo

Before: PR #3012 had reverted #1474, re-introducing manual useMemo and useCallback calls throughout the UI codebase.
After: Those manual memoization hooks are removed again. The React Compiler handles memoization automatically — useMemo(() => expr, [deps]) becomes const x = expr, and useCallback wrappers become plain function declarations.

The change is mechanical and applies uniformly: every useMemo is replaced with either an inline expression or an IIFE (for multi-statement bodies), every useCallback becomes a regular function, and form.handleSubmit wrappers are inlined at the definition site rather than the call site.

Why was #1474 reverted and now re-applied? PR #1474 removed manual memoization in favor of the React Compiler. PR #3012 reverted that change. This PR (#3017) reverts the revert, effectively re-landing the original cleanup.

.changeset/beige-bottles-tease.md · playground.tsx · chart.tsx · combobox.tsx

Pullfrog  | View workflow run | Triggered by Pullfrog | Using Claude Opus𝕏

Copy link
Copy Markdown
Contributor

@pullfrog pullfrog bot left a comment

Choose a reason for hiding this comment

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

Clean revert of #3012, effectively re-applying the useMemo/useCallback removal from #1474. The biome config on main already bans these imports, so this brings the code into compliance. All transformations are correct — plain expressions replace useMemo, function declarations replace useCallback, and biome-ignore comments are added where functions legitimately appear in dependency arrays. The channel-defaults-section.tsx refactoring is the most structural change and correctly isolates the 'use no memo' directive to the minimal ChannelDefaultsSectionInner component.

Pullfrog  | View workflow run | Using Claude Opus𝕏

Copy link
Copy Markdown
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(0) Total Issues | Risk: Low

This PR cleanly reverts PR #3012 to restore the project's React Compiler-based memoization policy. The changes are mechanical and aligned with the established codebase conventions documented in CLAUDE.md.

🔴❗ Critical (0) ❗🔴

None.

🟠⚠️ Major (0) 🟠⚠️

None.

🟡 Minor (0) 🟡

None.

💭 Consider (1) 💭

Inline Comments:

  • 💭 Consider: .changeset/beige-bottles-tease.md:4 Remove ignored package @inkeep/agents-docs from changeset

✅ APPROVE

Summary: This is a clean revert that correctly restores the React Compiler memoization policy. The biome.jsonc change re-enables the lint rule banning useCallback/useMemo imports, and all ~108 component/hook files are properly converted back to regular functions. The React Compiler (enabled for this project) will handle memoization automatically. One minor suggestion: the changeset includes @inkeep/agents-docs which is in the ignore list — this is harmless but slightly noisy.

Discarded (5)
Location Issue Reason Discarded
sidebar.tsx:88-101 useEffect function dependency pattern Valid pattern with React Compiler — reviewer self-assessed as "no change needed"
use-chat-activities-polling.ts:192-200 Hook returns functions recreated on render Valid pattern with React Compiler — compiler handles memoization
timeline-wrapper.tsx:227-242 Activities computed on every render Valid pattern with React Compiler — compiler auto-memoizes based on deps
slack-provider.tsx:62-80 Context value created inline Valid pattern with React Compiler — compiler memoizes context values
sidebar.tsx:103-116 Context value without useMemo Valid pattern with React Compiler — same as above
Reviewers (3)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-standards 0 0 0 0 0 0 0
pr-review-frontend 5 0 0 0 0 0 5
pr-review-devops 2 0 1 0 1 0 0
Total 7 0 1 0 1 0 5

Note: Frontend findings were all self-assessed by the reviewer as "correct patterns with React Compiler — no change needed", so they were discarded as non-issues.

---
"@inkeep/agents-manage-ui": patch
"@inkeep/agents-cli": patch
"@inkeep/agents-docs": patch
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.

💭 Consider: Remove ignored package from changeset

Issue: @inkeep/agents-docs is listed in the changeset but is in .changeset/config.json's ignore list. Changesets will skip it during versioning anyway.

Why: While harmless, including ignored packages adds noise and may confuse contributors about what actually gets released.

Fix:

Suggested change
"@inkeep/agents-docs": patch
"@inkeep/agents-manage-ui": patch
"@inkeep/agents-cli": patch

Refs:

@github-actions github-actions bot deleted a comment from claude bot Apr 5, 2026
Merged via the queue into main with commit 4082cfd Apr 5, 2026
31 checks passed
@dimaMachina dimaMachina deleted the revert-use-callback-use-memo branch April 5, 2026 01:45
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 5, 2026

🔎💬 Inkeep AI search and chat service is syncing content for source 'Inkeep Agent Framework Docs'

@itoqa
Copy link
Copy Markdown

itoqa bot commented Apr 5, 2026

Ito Test Report ✅

18 test cases ran. 1 additional finding, 17 passed.

The unified run covered 18 scenarios with 17 passes, confirming stable behavior across auth and invitation routing, device authorization (including malformed input handling), Slack link happy path, open-redirect defenses, traces/date/mobile/query-string resilience (with only controlled upstream telemetry-related errors), GitHub installation actions under rapid stress, members role and row-action integrity, submit idempotency, and cross-tab/back-forward session stability. The only failure was a medium-severity backend issue where a previously consumed Slack link token is still accepted on replay (POST /work-apps/slack/users/link/verify-token returns 200 due to JWT/schema validation without one-time-use tracking and an idempotent existing-link success path), weakening one-time-link security though identified as a pre-existing defect rather than introduced by this PR.

✅ Passed (17)
Category Summary Screenshot
Adversarial Malicious returnUrl payloads were sanitized and did not redirect to external domains in login or invitation paths. ADV-1
Adversarial Device form accepted valid formatted codes while script, overlong, and unicode-confusable payloads were sanitized or rejected safely. ADV-3
Adversarial Encoded and abusive query strings did not trigger script execution or crashes, and back-link navigation remained stable. ADV-5
Adversarial Rage-click and concurrent action stress remained stable with expected in-flight protections and coherent final state. ADV-6
Edge With populated rows, middle-row action opened the expected dialog and maintained row identity without mismatched targeting. EDGE-1
Edge Custom date range interactions, including partial-style inputs, remained stable and returned controlled non-5xx behavior. EDGE-2
Edge Session remained stable through login-return flow, invitation refresh recovered to deterministic handled state, repeated back/forward across members/settings/billing stayed coherent, and cross-tab /link refresh did not corrupt auth; post-churn request activity stayed bounded. EDGE-3
Edge Rapid Enter/click stress on dataset create yielded one resulting entity with submit disabling preventing duplicates. EDGE-4
Edge Mobile iPhone-12 traces flow remained usable; date-range change, AI Calls back navigation, and /link helper state worked. EDGE-6
Happy-path Login flow kept an internal return URL, completed admin sign-in, and redirected authenticated /login visits back to /default/projects without looping. ROUTE-1
Happy-path Invitation was accepted through onboarding, redirected to /default/projects, and replay attempts returned controlled invalid/used behavior without 5xx errors. ROUTE-2
Happy-path Device approve and deny flows reached expected terminal states without spinner lock, and malformed API payloads were handled with controlled 400 responses. ROUTE-3
Happy-path Valid Slack link token completed successfully, refresh stayed stable, and /link without token showed helper guidance. ROUTE-4
Happy-path Re-test confirmed Traces -> AI Calls/Tool Calls back-links preserve query context; observed /api/traces 500s were upstream telemetry availability issues, not a product defect. ROUTE-5
Happy-path GitHub installations list/detail actions completed with expected state transitions and no server errors. ROUTE-6
Happy-path Admin successfully performed member->admin and admin->member transitions, completed project-access follow-up, and revoked a pending invitation with successful role-update responses. ROUTE-7
Happy-path Re-check showed single mutation submits for dataset/project/scheduled-trigger paths, with submit locking in code and no duplicate-write regression. ROUTE-8
ℹ️ Additional Findings (1)

These findings are unrelated to the current changes but were observed during testing.

Category Summary Screenshot
Adversarial 🟠 Replayed consumed Slack link token is accepted with success instead of returning a controlled 4xx rejection. ADV-2
🟠 Replayed Slack link token is accepted after first use
  • What failed: A token that should be single-use is accepted again and returns 200 success on replay, while expected behavior is a controlled rejection (4xx) after first successful consumption.
  • Impact: Replayed Slack link tokens remain usable during their validity window, weakening one-time-link security guarantees. If a token leaks, it can be reused instead of forcing a fresh /inkeep link flow.
  • Steps to reproduce:
    1. Sign in with a normal user session.
    2. Link Slack once with a valid token via /link?token=.
    3. Submit the same token again to POST /work-apps/slack/users/link/verify-token.
    4. Observe the endpoint returns 200 success instead of rejecting replay with a controlled 4xx.
  • Stub / mock context: Slack replay validation used local seeded tokens and direct authenticated calls to the link verification endpoint to compare expired, tampered, and replayed-valid behavior. No mocked endpoint responses or route interception were applied.
  • Code analysis: I inspected the Slack token verifier and verify-token route in the backend. The verifier only checks JWT validity/schema and does not track token consumption, and the route explicitly returns idempotent success when a mapping already exists for the same user.
  • Why this is likely a bug: Production code lacks one-time-use enforcement and explicitly treats replay with the same user as success, directly enabling the observed replay acceptance.

Relevant code:

packages/agents-core/src/utils/slack-link-token.ts (lines 117-154)

export async function verifySlackLinkToken(token: string): Promise<VerifySlackLinkTokenResult> {
  const result = await verifyJwt(token, { issuer: ISSUER, audience: AUDIENCE });

  if (!result.valid || !result.payload) {
    return {
      valid: false,
      error: result.error,
    };
  }

  const parseResult = SlackLinkTokenPayloadSchema.safeParse(result.payload);
  if (!parseResult.success) {
    return {
      valid: false,
      error: `Invalid token schema: ${parseResult.error.issues.map((e) => e.message).join(', ')}`,
    };
  }

  return {
    valid: true,
    payload: parseResult.data,
  };
}

packages/agents-work-apps/src/slack/routes/users.ts (lines 194-213)

const existingLink = await findWorkAppSlackUserMapping(runDbClient)(
  tenantId,
  slackUserId,
  teamId,
  'work-apps-slack'
);

if (existingLink && existingLink.inkeepUserId === inkeepUserId) {
  return c.json({
    success: true,
    linkId: existingLink.id,
    slackUsername: existingLink.slackUsername || undefined,
    slackTeamId: teamId,
    tenantId,
  });
}

Commit: 004b05d

View Full Run


Tell us how we did: Give Ito Feedback

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.

1 participant