Skip to content

chore(release): staging to production - 2026.02.13 - #959

Merged
maxtechera merged 12 commits into
productionfrom
staging
Feb 13, 2026
Merged

chore(release): staging to production - 2026.02.13#959
maxtechera merged 12 commits into
productionfrom
staging

Conversation

@github-actions

@github-actions github-actions Bot commented Feb 12, 2026

Copy link
Copy Markdown

🚀 Release: Staging to Production

Release Date: 2026-02-13

Changes in this release

  • fix(AGENT-654): change marketplace AppBar position from fixed to relative (f3468e2)
  • feat(AGENT-683): refactor AnswerAgent MCP to use standard credential pattern (669beb4)
  • refactor(AGENT-676): hoist applyCredentialToNode to module scope, add null guard (dfca65b)
  • refactor(AGENT-676): extract credential helper, fix let to const (d2a52d7)
  • fix(AGENT-676): add error logging to credential extraction catch block (46a33f5)
  • fix(AGENT-676): use live canvas state for credential modal (141540e)
  • fix(AGENT-676): simplify credential save to single flow, fix stale closure (3356943)
  • fix(AGENT-676): address PR review feedback for race condition and null safety (0f164d5)
  • fix(AGENT-676): prevent quick setup from overwriting unsaved canvas (4142ce7)

This PR is automatically created/updated when commits are pushed to staging.
Merging this PR will trigger the release workflow to create a new GitHub release.

Diego and others added 8 commits February 10, 2026 15:36
When the credential setup modal runs on an open canvas, apply
credentials directly to the live ReactFlow nodes and mark the canvas
dirty instead of persisting to the backend (which would silently
overwrite any unsaved node edits).

- Read live canvas credentials via processFlowCredentials
- Add skipRefetch flag so credential-updated event doesn't re-fetch
- Sync AsyncDropdown internal value when external prop changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…l safety

- AsyncDropdown: guard useEffect to skip redundant setInternalValue calls
- SidekickSetupModal: add optional chaining on processFlowCredentials result

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…osure

Unify handleModalAssign into a single path that always saves to backend,
then applies credentials to live canvas nodes for immediate UI feedback.
Skip refetch only when canvas is open to preserve unsaved changes.

Remove over-engineered canvas/non-canvas split, SET_DIRTY dispatch,
processFlowCredentials import, and canvasNodes/liveCredentials computation.

Fix AsyncDropdown stale closure by removing manual equality check in useEffect.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Read credentials and flow data from reactFlowInstance instead of stale
SWR/backend data so unsaved nodes appear in QuickSetup and credential
saves preserve canvas layout. Also listen for credentials-updated event
in CredentialInputHandler to remount AsyncDropdown after new credentials
are created.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract applyCredentialToNode helper to deduplicate node mapping logic
in SidekickSetupModal. Change let to const for useState destructuring
in AsyncDropdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… null guard

Move helper outside component to avoid re-creation on each render and add
!node.data early return for null safety.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…erwrites-unsaved-canvas

fix(AGENT-676): prevent quick setup from overwriting unsaved canvas
@vercel

vercel Bot commented Feb 12, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
answerai-docs Building Building Preview Feb 12, 2026 4:26pm
the-answerai Building Building Preview Feb 12, 2026 4:26pm

Request Review

bradtaylorsf and others added 4 commits February 12, 2026 13:09
…pattern

BREAKING CHANGE: AnswerAgent MCP now requires credential configuration instead
of automatic API key lookup from the database.

- Create AnswerAgentApi credential with apiKey and instanceDomain fields
- Replace custom getUserApiKey() database query with getCredentialData/getCredentialParam
- Add instance domain support for connecting to other AnswerAgent instances
- Fix env variable name to ANSWERAGENT_AI_API_BASE_URL (matching MCP package)
- Add fallback chain: credential domain → chatflowDomain → API_HOST → FLOWISE_DOMAIN
- Bump version from 1.0 to 2.0
- Link to /sidekick-studio/apikey for API key management

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tive

Back button in marketplace template detail view was hidden behind
global navigation due to AppBar using position='fixed'. Changed to
position='relative' to match the working v2 implementation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ce-back-button-fix

fix(AGENT-654): Change marketplace AppBar position from fixed to relative
…ragent-mcp-credential-pattern

feat(AGENT-683): Fix AnswerAgent MCP to use standard credential pattern
@github-actions github-actions Bot changed the title chore(release): staging to production - 2026.02.12 chore(release): staging to production - 2026.02.13 Feb 13, 2026
@maxtechera
maxtechera merged commit e53387d into production Feb 13, 2026
5 of 10 checks passed
@maxtechera
maxtechera temporarily deployed to staging - aai-unified2-flowise-moonstruck February 13, 2026 16:58 — with Render Inactive
@claude

claude Bot commented Feb 13, 2026

Copy link
Copy Markdown

🔍 Code Review: Release staging to production - 2026.02.13

I've reviewed this release PR containing 9 commits across 8 files with 141 additions and 94 deletions. Here's my analysis:


Strengths

1. AGENT-676: Excellent Canvas State Management

The credential modal refactoring is well-architected:

  • Live Canvas State: Properly reads from reactFlowInstance to avoid stale data
  • No Overwrites: skipRefetch flag elegantly prevents loss of unsaved canvas changes
  • Single Flow: Removed over-engineered canvas/non-canvas split for cleaner logic
  • Proper Error Handling: Try-catch blocks with logging at critical points

2. AGENT-683: Standard Credential Pattern

Excellent refactoring of AnswerAgent MCP:

  • Breaking Change Properly Documented: Clear BREAKING CHANGE notice in commit
  • Follows Flowise Patterns: Uses getCredentialData/getCredentialParam instead of direct DB queries
  • Instance Domain Support: Adds flexibility to connect to different AnswerAgent instances
  • Removed 72 Lines of Complexity: Eliminated custom getUserApiKey() method

3. Code Quality

  • Hoisted Helper Function: applyCredentialToNode moved to module scope (performance improvement)
  • Proper Hooks: useEffect properly listens to credentials-updated events
  • Immutable Updates: Correct use of React state updates via callbacks

⚠️ Issues & Concerns

🔴 Critical: Security & Multi-tenancy

1. Missing organizationId Filtering (AnswerAgent Credential)

The new credential in AnswerAgentApi.credential.ts follows Flowise patterns correctly, but I want to verify: Does the credential system automatically enforce organizationId filtering?

Location: packages/components/credentials/AnswerAgentApi.credential.ts:23-32

The credential stores:

  • API Key (password field)
  • Instance Domain (optional string)

Question: Are credentials automatically scoped to the user's organization when retrieved via getCredentialData? If not, this could allow cross-organization credential access.


🟡 Moderate Issues

1. Potential Race Condition in AsyncDropdown

// packages/ui/src/ui-component/dropdown/AsyncDropdown.jsx:98-100
useEffect(() => {
    setInternalValue(value ?? 'choose an option')
}, [value])

Issue: This useEffect updates internalValue whenever the external value prop changes. While the commit message says "fix stale closure," this could cause unnecessary re-renders.

Concern: If value changes rapidly (e.g., during credential modal operations), this could cause flickering in the UI.

Recommendation: Add equality check:

useEffect(() => {
    if (value \!== internalValue) {
        setInternalValue(value ?? 'choose an option')
    }
}, [value, internalValue])

2. Silent Error Handling in SidekickSetupModal

// packages/ui/src/components/SidekickSetupModal.jsx:215-222
try {
    if (reactFlowInstance) {
        const { allCredentials } = extractAllCredentials(reactFlowInstance.toObject())
        if (allCredentials?.length) effectiveCredentials = allCredentials
    }
} catch (error) {
    console.error('[SidekickSetupModal] Failed to extract credentials from canvas:', error)
}

Issue: Error is caught and logged, but the modal continues with potentially stale credentialsToShow data. Users might not realize the modal is showing outdated credential requirements.

Recommendation: Show a warning toast to the user when credential extraction fails:

catch (error) {
    console.error('[SidekickSetupModal] Failed to extract credentials from canvas:', error)
    enqueueSnackbar({
        message: 'Warning: Could not read credentials from canvas. Showing saved credential requirements instead.',
        options: { variant: 'warning' }
    })
}

3. Missing Null Guard in applyCredentialToNode

// packages/ui/src/components/SidekickSetupModal.jsx:28-40
const applyCredentialToNode = (node, credentialAssignments) => {
    if (\!credentialAssignments[node.id] || \!node.data) return node
    return {
        ...node,
        data: {
            ...node.data,
            credential: credentialAssignments[node.id],
            inputs: {
                ...node.data.inputs,  // ⚠️ What if node.data.inputs is undefined?
                [FLOWISE_CREDENTIAL_ID]: credentialAssignments[node.id]
            }
        }
    }
}

Issue: Doesn't guard against node.data.inputs being undefined.

Recommendation:

inputs: {
    ...(node.data.inputs || {}),
    [FLOWISE_CREDENTIAL_ID]: credentialAssignments[node.id]
}

4. Environment Variable Fallback Chain Could Fail

// packages/components/credentials/AnswerAgentApi.credential.ts:28
default: process.env.API_HOST || process.env.FLOWISE_DOMAIN || '',

Issue: This runs in the browser context (credential UI), where process.env.API_HOST might not be available (Next.js doesn't expose non-NEXT_PUBLIC_* vars to the browser).

Recommendation: Use NEXT_PUBLIC_API_HOST or fetch from server-side:

default: process.env.NEXT_PUBLIC_API_HOST || '',

Or better yet, fetch the default from an API route that has access to server-side env vars.


5. AGENT-683: Wrong Environment Variable Name

// packages/components/nodes/tools/MCP/AnswerAgent/AnswerAgentMCP.ts:134
env: {
    ANSWERAGENT_AI_API_BASE_URL: apiHost,
    ANSWERAGENT_AI_API_TOKEN: apiKey
}

The commit message says "Fix env variable name to ANSWERAGENT_AI_API_BASE_URL (matching MCP package)" but I cannot verify this is correct without seeing the MCP package source.

Action Required: Please verify that the @answerai/answeragent-mcp package expects ANSWERAGENT_AI_API_BASE_URL and not ANSWERAGENT_AI_API_HOST.


🟢 Minor Issues

1. AGENT-654: Marketplace AppBar Position Change

// packages/ui/src/views/marketplaces/MarketplaceCanvas.jsx:68
position='relative'  // Changed from 'fixed'

Issue: This is a UI fix but there's no screenshot or E2E test to verify the back button is now visible.

Recommendation: Add a visual regression test or E2E test to prevent regression.


2. Inconsistent Commit Message Format

Some commits follow conventional commits properly:

  • feat(AGENT-683): refactor AnswerAgent MCP...
  • fix(AGENT-676): prevent quick setup...

Others are merge commits:

  • Merge pull request #953...

Note: This is fine for a release PR, but future feature PRs should squash merge commits.


🧪 Testing Concerns

Missing Test Coverage

  1. No E2E Tests for Credential Modal Flow

    • Test: Open canvas → trigger quick setup → assign credentials → verify canvas not refetched
  2. No Tests for AnswerAgent MCP with Credential

    • Test: Create AnswerAgent MCP node → assign credential → verify MCP server starts with correct env vars
  3. No Tests for AsyncDropdown useEffect Fix

    • Test: Rapidly change credential value → verify no flickering/race conditions

📊 Performance Considerations

Positive

  • Hoisting applyCredentialToNode to module scope prevents recreation on each render
  • skipRefetch flag prevents unnecessary canvas re-fetches

⚠️ Potential Concerns

  • extractAllCredentials(reactFlowInstance.toObject()) is called on every render when reactFlowInstance exists. Consider memoization:
const effectiveCredentials = useMemo(() => {
    try {
        if (reactFlowInstance) {
            const { allCredentials } = extractAllCredentials(reactFlowInstance.toObject())
            return allCredentials?.length ? allCredentials : credentialsToShow
        }
    } catch (error) {
        console.error('[SidekickSetupModal] Failed to extract credentials:', error)
    }
    return credentialsToShow
}, [reactFlowInstance, credentialsToShow])

🔒 Security Checklist

Credentials use password field type
No hardcoded secrets
Multi-tenancy enforcement for credentials (needs verification)
Error messages don't leak sensitive info
Uses standard Flowise credential system


📝 Recommendations for Merging

Before Merging:

  1. Verify credential system automatically scopes by organizationId
  2. Fix node.data.inputs null guard in applyCredentialToNode
  3. Fix environment variable access in credential default value
  4. Verify ANSWERAGENT_AI_API_BASE_URL matches MCP package expectations

After Merging:

  1. ⏱️ Add E2E tests for credential modal with canvas open
  2. ⏱️ Add visual regression test for marketplace AppBar
  3. ⏱️ Monitor for credential extraction failures in production logs
  4. ⏱️ Document the breaking change for AnswerAgent MCP in release notes

🎯 Overall Assessment

Verdict: ⚠️ Conditional Approval with Required Fixes

The Good: This is a well-structured release with thoughtful architectural improvements. The credential modal refactoring is excellent, and the AnswerAgent MCP standardization is a significant improvement.

The Concerns: A few security and robustness issues should be addressed before merging to production:

  • Multi-tenancy verification for credentials
  • Null safety improvements
  • Environment variable handling

Confidence Level: 85% - Code quality is high, but the critical items need verification.


📖 References

  • TheAnswer CLAUDE.md: Multi-tenancy patterns
  • packages/server/CLAUDE.md: 4-layer architecture
  • packages/components/CLAUDE.md: Component credential patterns

Reviewed by: Claude Sonnet 4.5
Review Date: 2026-02-13
Files Changed: 8 files (+141/-94)
Commits Reviewed: 9 commits from staging

@claude

claude Bot commented Feb 13, 2026

Copy link
Copy Markdown

PR Review: Staging to Production Release (2026-02-13)

📋 Summary

This release contains 9 commits addressing credential management improvements (AGENT-676), AnswerAgent MCP refactoring (AGENT-683), and a marketplace UI fix (AGENT-654). Overall, the changes show good engineering discipline with iterative refinement through multiple commits.


✅ Strengths

  1. Iterative Problem Solving: The AGENT-676 fix shows excellent iterative refinement through commits 1-7, progressively addressing:

    • Race conditions and null safety
    • Stale closure issues
    • Over-engineering concerns
    • Code deduplication
  2. Proper Credential Pattern: The AnswerAgent MCP refactor (commit 8) correctly migrates to standard Flowise credential pattern following repository conventions.

  3. Clear Commit Messages: All commits follow conventional commit format with descriptive messages and co-authorship attribution.


🔍 Code Quality Issues

1. AsyncDropdown useEffect Dependency Warning ⚠️

// packages/ui/src/ui-component/dropdown/AsyncDropdown.jsx:96
useEffect(() => {
    setInternalValue(value ?? 'choose an option')
}, [value])

Issue: Missing internalValue in dependency array could cause React warnings. However, this appears intentional to avoid infinite loops.

Recommendation: Add ESLint disable comment if intentional:

useEffect(() => {
    setInternalValue(value ?? 'choose an option')
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [value])

2. Missing Error Handling in SidekickSetupModal 🔴

// packages/ui/src/components/SidekickSetupModal.jsx:228
try {
    if (reactFlowInstance) {
        const { allCredentials } = extractAllCredentials(reactFlowInstance.toObject())
        if (allCredentials?.length) effectiveCredentials = allCredentials
    }
} catch (error) {
    console.error('[SidekickSetupModal] Failed to extract credentials from canvas:', error)
}

Issue: Error is logged but not shown to user. If credential extraction fails, user may see incorrect/incomplete credential list.

Recommendation: Add user notification on error:

} catch (error) {
    console.error('[SidekickSetupModal] Failed to extract credentials from canvas:', error)
    enqueueSnackbar({
        message: 'Warning: Could not load all credentials from canvas',
        options: { variant: 'warning' }
    })
}

3. Potential Breaking Change Not Clearly Documented ⚠️

The AnswerAgent MCP v1.0 → v2.0 is marked as BREAKING CHANGE in commit message, but:

  • No migration guide provided
  • No backward compatibility layer
  • Users upgrading will need to reconfigure all AnswerAgent MCP nodes

Recommendation: Add migration documentation or consider a deprecation path.


🔒 Security Review

No security issues found

  • Credentials properly handled via getCredentialData/getCredentialParam
  • No hardcoded secrets
  • API keys stored securely in credential system
  • No XSS/injection vulnerabilities introduced

🎯 Architecture & Best Practices

✅ Follows Repository Patterns

  1. Credential System: AnswerAgent MCP now correctly uses standard credential pattern
  2. Error Handling: Uses InternalFlowiseError pattern (inherited)
  3. Module Scope: applyCredentialToNode hoisted to module scope (good performance practice)

🟡 Minor Concerns

  1. Helper Function Placement: applyCredentialToNode at module scope is good, but consider moving to a shared utility if used elsewhere.

  2. Magic Strings: FLOWISE_CREDENTIAL_ID constant is used correctly, but ensure it's consistently imported from constants file.

  3. Event-Driven Communication: The credentials-updated custom event pattern works but could be fragile. Consider:

    • Adding event type constants
    • TypeScript typing for event details
    • Centralized event bus

🧪 Testing Considerations

Missing Test Coverage: No tests added for:

  • Credential extraction from live canvas
  • skipRefetch flag behavior
  • AnswerAgent MCP credential integration
  • AsyncDropdown value synchronization

Recommendation: Add E2E tests for:

// apps/web/e2e/tests/credentials.spec.ts
test('Quick setup preserves unsaved canvas changes', async ({ page }) => {
    // 1. Open canvas and add nodes
    // 2. Trigger credential setup without saving
    // 3. Verify unsaved changes preserved
})

🚀 Performance Considerations

  1. Event Listener Cleanup: ✅ Properly cleaned up in CredentialInputHandler
  2. Unnecessary Re-renders: The AsyncDropdown useEffect may cause extra renders if value changes frequently
  3. ReactFlow State Updates: Using setNodes with mapper function is efficient ✅

📝 Documentation

Missing:

  • Migration guide for AnswerAgent MCP v2.0
  • Explanation of skipRefetch flag in code comments
  • JSDoc for applyCredentialToNode helper

Recommendation: Add inline documentation:

/**
 * Applies credential assignment to a ReactFlow node.
 * Preserves existing node structure and only updates credential-related fields.
 * 
 * @param node - ReactFlow node to update
 * @param credentialAssignments - Map of nodeId -> credentialId
 * @returns Updated node or original if no assignment exists
 */
const applyCredentialToNode = (node, credentialAssignments) => { ... }

🎯 Recommendations Summary

Must Fix Before Merge 🔴

None - code is functional

Should Fix Soon 🟡

  1. Add user notification for credential extraction errors
  2. Add ESLint disable comment for intentional useEffect behavior
  3. Add E2E tests for credential quick setup flow

Nice to Have 💡

  1. Migrate guide for AnswerAgent MCP breaking change
  2. JSDoc comments for helper functions
  3. Consider TypeScript for event payloads

✅ Approval Status

APPROVED - This PR is ready for production deployment with minor follow-up recommendations.

The iterative refinement through 7 commits for AGENT-676 demonstrates excellent problem-solving. The AnswerAgent MCP refactor correctly follows repository patterns. The marketplace UI fix is straightforward and safe.


Reviewed by: Claude Sonnet 4.5
Review Date: 2026-02-13

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants