Files
Jocelyn LinandClaude Opus 4.6 fedc6ebc82 feat(agentflow): enhance state management with StateKeyValueInput and variable support (#6119)
* feat(agentflow): enhance state management with StateKeyValueInput and variable support

- Added StateKeyValueInput component for managing key-value pairs in flow state updates.
- Integrated VariableInput for value fields to support variable syntax.
- Updated MessagesInput and ExpandTextDialog to utilize variable items for enhanced user experience.
- Introduced new types for state updates in core types.
- Enhanced Jest tests to cover new functionality and ensure reliability.

This update improves the flexibility and usability of state management within the agentflow package.

* fix(agentflow): address PR #6119 review feedback

- Add autoFocus prop to VariableInput, apply in ExpandTextDialog for
  consistent focus behavior with RichTextEditor fallback
- Extract duplicated VariableItem→SuggestionItem mapping into shared
  toSuggestionItems utility, used by MessagesInput and NodeInputHandler
- Remove redundant default export from StateKeyValueInput

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* clear selected key and update dropdown when a state key is removed

* cleanup unused type

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-04-02 12:10:51 -07:00

87 lines
4.3 KiB
JavaScript

// Shared config inherited by both project types
const baseConfig = {
preset: 'ts-jest',
roots: ['<rootDir>/src'],
transform: {
'^.+\\.tsx?$': [
'ts-jest',
{
tsconfig: 'tsconfig.json'
}
]
},
testPathIgnorePatterns: ['/node_modules/', '/dist/'],
moduleNameMapper: {
'\\.(css|less|scss|sass)$': '<rootDir>/src/__mocks__/styleMock.js',
'\\.svg$': '<rootDir>/src/__mocks__/styleMock.js',
'^@/(.*)$': '<rootDir>/src/$1',
'^@test-utils/(.*)$': '<rootDir>/src/__test_utils__/$1',
// TipTap + lowlight ship ESM-only — Jest (CJS) cannot import them,
// so we redirect to lightweight CJS stubs under src/__mocks__/.
'^@tiptap/(.+)$': '<rootDir>/src/__mocks__/@tiptap/$1.ts',
'^lowlight$': '<rootDir>/src/__mocks__/lowlight.ts',
'^tippy\\.js$': '<rootDir>/src/__mocks__/tippy.js.ts',
// Bypass React.lazy wrappers — resolve Foo.lazy → Foo so tests render synchronously
'(.*)\\.lazy$': '$1'
}
}
module.exports = {
verbose: true,
collectCoverageFrom: [
'src/**/*.{ts,tsx}',
'!src/**/*.test.{ts,tsx}',
'!src/**/*.d.ts',
'!src/**/index.ts',
'!src/__mocks__/**',
'!src/__test_utils__/**',
'!src/infrastructure/api/hooks/**'
],
// text: per-folder table, text-summary: totals, lcov: HTML report at coverage/lcov-report/
coverageReporters: ['text', 'text-summary', 'lcov'],
coverageDirectory: 'coverage',
// 80% floor to catch regressions without blocking active development.
// Add new paths here as more modules gain test coverage.
coverageThreshold: {
'./src/*.ts': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/Agentflow.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/atoms/ArrayInput.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/atoms/ExpandTextDialog.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/atoms/MessagesInput.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/atoms/ScenariosInput.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/atoms/StateKeyValueInput.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
// Tier 3 UI atom — only the onChange/disabled/sync logic is tested, not styled internals
'./src/atoms/RichTextEditor.tsx': { branches: 30, functions: 50, lines: 50, statements: 50 },
'./src/core/': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/features/canvas/components/ConnectionLine.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
// Only getMinimumNodeHeight() is tested; the component is Tier 3 UI with no business logic
'./src/features/canvas/components/NodeOutputHandles.tsx': { branches: 0, functions: 10, lines: 30, statements: 30 },
'./src/features/canvas/containers/NodeInfoDialog.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/features/canvas/hooks/': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/features/generator/GenerateFlowDialog.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/features/node-editor/': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/features/node-palette/search.ts': { branches: 80, functions: 80, lines: 80, statements: 80 },
'./src/infrastructure/': { branches: 80, functions: 80, lines: 80, statements: 80 }
},
projects: [
// .test.ts → node (fast, no DOM)
{
...baseConfig,
displayName: 'unit',
testEnvironment: 'node',
testMatch: ['<rootDir>/src/**/*.test.ts']
},
// .test.tsx → jsdom (browser-like DOM for React components)
{
...baseConfig,
displayName: 'components',
testEnvironment: '<rootDir>/src/__test_utils__/jest-environment-jsdom.js',
testEnvironmentOptions: {
customExportConditions: ['']
},
testMatch: ['<rootDir>/src/**/*.test.tsx'],
setupFilesAfterEnv: ['@testing-library/jest-dom']
}
]
}