✨ Source component suggestions#787
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds AI-driven manual component suggestions: new Aegis feature and types, a composable to fetch/apply/revert/send-feedback for component suggestions, watcher and composable integrations, a UI wrapper component with tests, FlawForm integration replacing the old modal flow, minor AegisActions tooltip/layout fixes, and a changelog entry. ChangesComponent Suggestions Feature
🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 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 unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
src/components/Aegis/__tests__/AegisComponentActions.spec.ts (1)
79-114: ⚡ Quick winAdd a non-zero selection assertion to catch index-mapping regressions.
This test passes even when component logic ignores user-selected indices.
Proposed test hardening
- await aegisActions.vm.$emit('selectSuggestion', 0); - - expect(mockSelectSuggestion).toHaveBeenCalledWith(0); + await aegisActions.vm.$emit('selectSuggestion', 1); + expect(mockSelectSuggestion).toHaveBeenCalledWith(1);As per coding guidelines, "**: -Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/Aegis/__tests__/AegisComponentActions.spec.ts` around lines 79 - 114, The test currently only asserts a zero index selection which can mask index-mapping bugs; update the mocked useAegisSuggestComponents so selectedSuggestionIndex is a non-zero value (e.g., computed(() => 1)), ensure suggestedComponents/allSuggestions include at least two entries, then emit a non-zero selection from the AegisActions component (e.g., aegisActions.vm.$emit('selectSuggestion', 1)) and assert mockSelectSuggestion was called with that non-zero index (mockSelectSuggestion toHaveBeenCalledWith(1)) to catch regressions in index handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/Aegis/AegisActions.vue`:
- Line 123: Remove the trailing whitespace on the empty/partial tag near the
<span in AegisActions.vue (the fragment shown in the diff) so the line contains
no trailing spaces; edit the <span line to trim the trailing spaces and save to
satisfy the linter.
In `@src/components/Aegis/AegisComponentActions.vue`:
- Around line 38-48: handleSelectSuggestion currently hardcodes
selectSuggestion(0), dropping the original set/item indices and preventing
choosing alternate suggestion sets; change it to map the incoming _flatIndex
back to the corresponding suggestion-set index and item-index using
allSuggestions (or flatSuggestions with offsets) and call selectSuggestion with
the correct set index (and item index if selectSuggestion accepts it) so the UI
selection matches the flattened index; locate handleSelectSuggestion,
flatSuggestions and selectSuggestion to implement this index-mapping logic and
update any callers accordingly.
In `@src/components/FlawComments/FlawComments.vue`:
- Line 182: The CSS in FlawComments.vue currently sets "white-space: pre-line"
for rendered comment text which collapses repeated spaces/tabs and breaks
user-aligned formatting; replace that rule with "white-space: pre-wrap" (or
"white-space: pre" if wrapping must be avoided) in the same selector so line
breaks are preserved while still allowing wrapping, ensuring comment text and
code/log snippets keep their original spacing. Locate the white-space rule in
FlawComments.vue and update it to pre-wrap and verify comment history renders
aligned text correctly.
In `@src/composables/aegis/useAegisSuggestComponents.ts`:
- Around line 111-116: selectSuggestion currently assigns previousValue on every
invocation, which overwrites the original baseline and breaks revert; change the
logic in selectSuggestion (and the similar block around the later 126-131
region) so previousValue is only set when it is null/undefined (i.e., only on
the first selection in the session) and do not reassign it on subsequent calls;
refer to function selectSuggestion, the previousValue ref, and the revert logic
to ensure revert uses the preserved original value.
---
Nitpick comments:
In `@src/components/Aegis/__tests__/AegisComponentActions.spec.ts`:
- Around line 79-114: The test currently only asserts a zero index selection
which can mask index-mapping bugs; update the mocked useAegisSuggestComponents
so selectedSuggestionIndex is a non-zero value (e.g., computed(() => 1)), ensure
suggestedComponents/allSuggestions include at least two entries, then emit a
non-zero selection from the AegisActions component (e.g.,
aegisActions.vm.$emit('selectSuggestion', 1)) and assert mockSelectSuggestion
was called with that non-zero index (mockSelectSuggestion
toHaveBeenCalledWith(1)) to catch regressions in index handling.
🪄 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: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: 8ee179c7-6874-4109-8777-124ae175dc7e
⛔ Files ignored due to path filters (3)
src/components/Aegis/__tests__/__snapshots__/AegisComponentActions.spec.ts.snapis excluded by!**/*.snapsrc/components/__tests__/__snapshots__/FlawForm.spec.ts.snapis excluded by!**/*.snapsrc/views/__tests__/__snapshots__/FlawCreateView.spec.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (9)
CHANGELOG.mdsrc/components/Aegis/AegisActions.vuesrc/components/Aegis/AegisComponentActions.vuesrc/components/Aegis/__tests__/AegisComponentActions.spec.tssrc/components/FlawComments/FlawComments.vuesrc/components/FlawForm/FlawForm.vuesrc/composables/aegis/__tests__/useAegisSuggestComponents.spec.tssrc/composables/aegis/useAegisSuggestComponents.tssrc/types/aegisAI.ts
b507299 to
1e2192e
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/composables/aegis/__tests__/useAegisSuggestComponents.spec.ts (1)
57-65: ⚡ Quick winAdd regression tests for apply/revert state transitions (not just method existence).
The suite currently misses assertions for the core behavior of
suggestComponents()+revert(). Add cases that verify baseline restoration for[]andundefinedso revert regressions are caught.Example direction
+it('restores an empty-array baseline after revert', async () => { + mockValueRef.value = []; + // mock service response with one suggestion + // await result.suggestComponents() + // result.revert() + // expect(mockValueRef.value).toEqual([]) +}); + +it('restores an undefined baseline after revert', async () => { + mockValueRef.value = undefined; + // mock service response with one suggestion + // await result.suggestComponents() + // result.revert() + // expect(mockValueRef.value).toBeUndefined() +});Also applies to: 79-85
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/composables/aegis/__tests__/useAegisSuggestComponents.spec.ts` around lines 57 - 65, Add regression tests in useAegisSuggestComponents.spec.ts to assert actual state transitions for suggestComponents() and revert(): call useAegisSuggestComponents(mockContext, mockValueRef), invoke result.suggestComponents(...) to apply suggestions and assert that result.allSuggestions.value, result.hasAppliedSuggestion.value, result.selectedSuggestionIndex.value, and result.canShowFeedback.value reflect the applied state, then call result.revert() and assert the baseline is restored for two cases — when the original value ref was [] and when it was undefined — ensuring revert returns all affected refs to their original values; add parallel tests where applicable around the existing initialization test and the block around lines 79–85 so both scenarios are covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/Aegis/AegisComponentActions.vue`:
- Around line 68-76: The tooltip strings produced by the computed
suggestionTooltip (using hasAppliedSuggestion,
componentsSuggestionDetails.explanation, and getAIBotTooltip('components')) are
untrusted and later rendered with v-html in AegisActions, so sanitize/escape
them before returning: update suggestionTooltip to run the text through a safe
HTML sanitizer or escape function (e.g., strip or encode tags/entities) and
preserve newline replacements, or return a sanitized string variant for
AegisActions to render; ensure all branches (the title+explanation branch and
the aiBotTooltip branch) use the sanitizer/escape so no raw HTML reaches v-html.
In `@src/composables/aegis/useAegisSuggestComponents.ts`:
- Around line 36-37: The revert logic for the suggest component is mutating and
coercing baseline values (turning [] into null and forcing undefined to null);
update the stored baseline types and restore logic so the original value is
captured and restored exactly (preserve undefined vs null vs empty array).
Change previousValue to allow undefined (ref<string[] | null | undefined>), stop
coercing when saving baseline (store the raw value from the source field), and
update revert() to assign back the stored baseline exactly to the target field
(no conversion to null or []) while leaving selectedSuggestionIndex handling
unchanged.
---
Nitpick comments:
In `@src/composables/aegis/__tests__/useAegisSuggestComponents.spec.ts`:
- Around line 57-65: Add regression tests in useAegisSuggestComponents.spec.ts
to assert actual state transitions for suggestComponents() and revert(): call
useAegisSuggestComponents(mockContext, mockValueRef), invoke
result.suggestComponents(...) to apply suggestions and assert that
result.allSuggestions.value, result.hasAppliedSuggestion.value,
result.selectedSuggestionIndex.value, and result.canShowFeedback.value reflect
the applied state, then call result.revert() and assert the baseline is restored
for two cases — when the original value ref was [] and when it was undefined —
ensuring revert returns all affected refs to their original values; add parallel
tests where applicable around the existing initialization test and the block
around lines 79–85 so both scenarios are covered.
🪄 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: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: 0bc07bd8-3821-4a43-9931-7a14d8be1bf2
⛔ Files ignored due to path filters (3)
src/components/Aegis/__tests__/__snapshots__/AegisComponentActions.spec.ts.snapis excluded by!**/*.snapsrc/components/__tests__/__snapshots__/FlawForm.spec.ts.snapis excluded by!**/*.snapsrc/views/__tests__/__snapshots__/FlawCreateView.spec.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (8)
CHANGELOG.mdsrc/components/Aegis/AegisActions.vuesrc/components/Aegis/AegisComponentActions.vuesrc/components/Aegis/__tests__/AegisComponentActions.spec.tssrc/components/FlawForm/FlawForm.vuesrc/composables/aegis/__tests__/useAegisSuggestComponents.spec.tssrc/composables/aegis/useAegisSuggestComponents.tssrc/types/aegisAI.ts
| const suggestionTooltip = computed(() => { | ||
| if (hasAppliedSuggestion.value && componentsSuggestionDetails.value?.explanation) { | ||
| const title = isComponentsAIBot.value ? 'Generated by Aegis-AI-Bot' : 'Generated by Aegis-AI'; | ||
| return `${title}\n\n${componentsSuggestionDetails.value.explanation}`; | ||
| } | ||
| const aiBotTooltip = getAIBotTooltip('components'); | ||
| if (aiBotTooltip && aiBotTooltip !== 'Generated by Aegis-AI-Bot') { | ||
| return aiBotTooltip.replace(/<br><br>/g, '\n\n'); | ||
| } |
There was a problem hiding this comment.
Escape tooltip content before it reaches v-html.
These tooltip strings are untrusted and are later rendered via v-html in AegisActions, which creates an XSS path if HTML is present.
🔒 Suggested fix
+const escapeHtml = (value: string) => value
+ .replace(/&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, '&`#39`;');
+
const suggestionTooltip = computed(() => {
if (hasAppliedSuggestion.value && componentsSuggestionDetails.value?.explanation) {
const title = isComponentsAIBot.value ? 'Generated by Aegis-AI-Bot' : 'Generated by Aegis-AI';
- return `${title}\n\n${componentsSuggestionDetails.value.explanation}`;
+ return `${title}\n\n${escapeHtml(componentsSuggestionDetails.value.explanation)}`;
}
const aiBotTooltip = getAIBotTooltip('components');
if (aiBotTooltip && aiBotTooltip !== 'Generated by Aegis-AI-Bot') {
- return aiBotTooltip.replace(/<br><br>/g, '\n\n');
+ return escapeHtml(aiBotTooltip).replace(/<br><br>/g, '\n\n');
}
return '';
});🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/Aegis/AegisComponentActions.vue` around lines 68 - 76, The
tooltip strings produced by the computed suggestionTooltip (using
hasAppliedSuggestion, componentsSuggestionDetails.explanation, and
getAIBotTooltip('components')) are untrusted and later rendered with v-html in
AegisActions, so sanitize/escape them before returning: update suggestionTooltip
to run the text through a safe HTML sanitizer or escape function (e.g., strip or
encode tags/entities) and preserve newline replacements, or return a sanitized
string variant for AegisActions to render; ensure all branches (the
title+explanation branch and the aiBotTooltip branch) use the sanitizer/escape
so no raw HTML reaches v-html.
1e2192e to
c6b0028
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/composables/aegis/__tests__/useAegisSuggestComponents.spec.ts (1)
57-85: ⚡ Quick winAdd behavioral tests for apply/revert/feedback flows, not just API shape.
Current tests only verify defaults and function presence. Please add focused cases for: successful suggestion apply, exact revert for
undefined/null/[], and one-time feedback gating after submission.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/composables/aegis/__tests__/useAegisSuggestComponents.spec.ts` around lines 57 - 85, Add behavioral tests to useAegisSuggestComponents: write tests that cover applying a suggestion (call selectSuggestion or applySuggestion and assert allSuggestions changes, hasAppliedSuggestion becomes true, selectedSuggestionIndex updates, and mockValueRef reflects applied value), reverting behavior (set value to undefined/null/[] then call revert and assert value is restored exactly and hasAppliedSuggestion resets), and feedback gating (call submitFeedback once and assert canShowFeedback toggles so subsequent feedback attempts are blocked and hasAppliedSuggestion/feedback state reflect the one-time submission). Use existing symbols: useAegisSuggestComponents, selectSuggestion/applySuggestion, revert, submitFeedback, canShowFeedback, hasAppliedSuggestion, selectedSuggestionIndex, allSuggestions, mockContext and mockValueRef to locate methods and state to assert.src/components/Aegis/AegisComponentActions.vue (1)
33-34: ⚡ Quick winAvoid null-unsafe casting for
aegisContextbefore passing into the composable.
aegisContextis nullable by prop contract, but this cast erases that and weakens type safety at the integration boundary. Prefer handlingnullexplicitly (or updating the composable signature to accept nullable input) instead of forcing a non-null type.As per coding guidelines, "**: -Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/Aegis/AegisComponentActions.vue` around lines 33 - 34, The code unsafely casts props.aegisContext to AegisSuggestionContextRefs before passing it into the composable; remove the non-null assertion and handle the nullable prop explicitly by either (a) only invoking the composable or passing the context when props.aegisContext is non-null (e.g., guard with if (props.aegisContext) { /* call composable with props.aegisContext */ }), or (b) update the composable's parameter type to accept AegisSuggestionContextRefs | null/undefined and handle null inside the composable; target the symbol props.aegisContext and the composable call site (the function that currently receives AegisSuggestionContextRefs) and apply one of these fixes to preserve type safety.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/composables/aegis/useAegisSuggestComponents.ts`:
- Around line 96-103: getSuggestion() currently trusts the untyped API response
and assigns data.components directly, which can be a non-array and later break
selectSuggestion() when it spreads components; add a runtime guard in
getSuggestion() to validate that data.components is an Array and every item is a
string (use Array.isArray(data.components) && data.components.every(item =>
typeof item === 'string')); if the check fails, set components to null (or an
empty array if preferred) before returning the ComponentsSuggestionDetails so
selectSuggestion() and valueRef spreading cannot be corrupted. Ensure you
reference the returned property name "components" and the type
ComponentsSuggestionDetails when applying the guard and mapping/casting the
validated value.
---
Nitpick comments:
In `@src/components/Aegis/AegisComponentActions.vue`:
- Around line 33-34: The code unsafely casts props.aegisContext to
AegisSuggestionContextRefs before passing it into the composable; remove the
non-null assertion and handle the nullable prop explicitly by either (a) only
invoking the composable or passing the context when props.aegisContext is
non-null (e.g., guard with if (props.aegisContext) { /* call composable with
props.aegisContext */ }), or (b) update the composable's parameter type to
accept AegisSuggestionContextRefs | null/undefined and handle null inside the
composable; target the symbol props.aegisContext and the composable call site
(the function that currently receives AegisSuggestionContextRefs) and apply one
of these fixes to preserve type safety.
In `@src/composables/aegis/__tests__/useAegisSuggestComponents.spec.ts`:
- Around line 57-85: Add behavioral tests to useAegisSuggestComponents: write
tests that cover applying a suggestion (call selectSuggestion or applySuggestion
and assert allSuggestions changes, hasAppliedSuggestion becomes true,
selectedSuggestionIndex updates, and mockValueRef reflects applied value),
reverting behavior (set value to undefined/null/[] then call revert and assert
value is restored exactly and hasAppliedSuggestion resets), and feedback gating
(call submitFeedback once and assert canShowFeedback toggles so subsequent
feedback attempts are blocked and hasAppliedSuggestion/feedback state reflect
the one-time submission). Use existing symbols: useAegisSuggestComponents,
selectSuggestion/applySuggestion, revert, submitFeedback, canShowFeedback,
hasAppliedSuggestion, selectedSuggestionIndex, allSuggestions, mockContext and
mockValueRef to locate methods and state to assert.
🪄 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: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: a41888ca-128d-4157-87b3-0a77326a99c0
⛔ Files ignored due to path filters (3)
src/components/Aegis/__tests__/__snapshots__/AegisComponentActions.spec.ts.snapis excluded by!**/*.snapsrc/components/__tests__/__snapshots__/FlawForm.spec.ts.snapis excluded by!**/*.snapsrc/views/__tests__/__snapshots__/FlawCreateView.spec.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (8)
CHANGELOG.mdsrc/components/Aegis/AegisActions.vuesrc/components/Aegis/AegisComponentActions.vuesrc/components/Aegis/__tests__/AegisComponentActions.spec.tssrc/components/FlawForm/FlawForm.vuesrc/composables/aegis/__tests__/useAegisSuggestComponents.spec.tssrc/composables/aegis/useAegisSuggestComponents.tssrc/types/aegisAI.ts
✅ Files skipped from review due to trivial changes (1)
- CHANGELOG.md
c6b0028 to
34e92c9
Compare
| import { useToastStore } from '@/stores/ToastStore'; | ||
| import type { ComponentsSuggestionDetails } from '@/types/aegisAI'; | ||
|
|
||
| export type UseAegisSuggestComponentsReturn = { |
There was a problem hiding this comment.
I think this type isn't needed, since it just enforces the return type of a function used locally. I think if we want to pay the maintenance cost of having a more generic interface for suggestions composables, then that would add more value.
There was a problem hiding this comment.
if hasMultipleSuggestions is only gating logic that deals with interactions between allsuggestions then it could be runtime rather than type logic allSuggestions.value[0].length === 1 and could therefore be a function.
superbuggy
left a comment
There was a problem hiding this comment.
One suggestion that isn't a change request; feel free to disagree. Looks good otherwise.
1414e27 to
42b2e8c
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/composables/aegis/useAegisSuggestion.ts (1)
269-273:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPrevent applying a scalar
stringto the componentsstring[]model.For
fieldName === 'components', Line 275 turns each component into a selectable suggestion item, and Line 272 appliescurrentSuggestiondirectly. That can write a singlestringinto themodelValuecontract (string[] | null | undefinedinsrc/components/Aegis/AegisComponentActions.vue, Line 17), causing type-shape drift in form state.As per coding guidelines, "**: -Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."
Proposed fix
@@ function selectSuggestion(index: number) { if (!allSuggestions.value?.[index]) return; selectedSuggestionIndex.value = index; + if (fieldName === 'components') { + const componentsSuggestion = details.value.components; + if (Array.isArray(componentsSuggestion) && componentsSuggestion.length > 0) { + aegisSuggestionWatcher.applyAISuggestion(componentsSuggestion); + } + return; + } if (currentSuggestion.value) aegisSuggestionWatcher.applyAISuggestion(currentSuggestion.value); } @@ - const hasMultipleSuggestions = computed(() => allSuggestions.value.length > 1); + const hasMultipleSuggestions = computed( + () => (fieldName === 'components' ? false : allSuggestions.value.length > 1), + );Also applies to: 275-279, 290-290
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/composables/aegis/useAegisSuggestion.ts` around lines 269 - 273, selectSuggestion may call aegisSuggestionWatcher.applyAISuggestion with currentSuggestion that is a scalar string when fieldName === 'components', which can violate the component's model type (expects string[] | null | undefined); update selectSuggestion (and other places noted: the block around lines handling components, and where currentSuggestion is applied) to detect when fieldName === 'components' and currentSuggestion is a string and instead pass an array (e.g., wrap the string in [currentSuggestion]) or otherwise convert to the expected string[] shape before calling aegisSuggestionWatcher.applyAISuggestion so the modelValue contract is preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/composables/aegis/useAegisSuggestion.ts`:
- Around line 170-177: The suggestComponents flow is too strict and mismatches
the API contract: update suggestComponents (and the call site that invokes
analyzeCVEWithContext for "suggest-affected-components") to (1) unwrap the
actual payload (check for data.output and use that when present), (2) validate
that data.components is an array of strings (every item typeof === 'string' and
length > 0) instead of only checking Array.isArray/length, and (3) when calling
analyzeCVEWithContext for the affected-components path include detail: true in
the options so the analyzer returns the detailed structure — mirror the handling
used in useAegisSuggestComponents.ts (lines around its validate/unwrapping
logic) to avoid rejecting valid responses and silently suppressing suggestions.
In `@src/composables/aegis/useAISuggestionsWatcher.ts`:
- Around line 14-19: The watcher in useAISuggestionsWatcher uses strict
reference inequality (newValue !== originalSuggestion.value && newValue !==
oldValue), which misses in-place mutations for string[] fields (e.g., fieldName
'components'); change the comparison to deep/value equality: compute normalized
representations (e.g., for arrays use JSON.stringify or a deepEqual helper) and
compare those strings/values instead of references when checking against
originalSuggestion.value and oldValue, while keeping the rest of the logic
(hasAppliedSuggestion, hasPartialModification, hasTrackedPartialChange,
trackAIChange) the same; also use the same normalization when building
metadataValue so array changes are detected and tracked correctly.
---
Outside diff comments:
In `@src/composables/aegis/useAegisSuggestion.ts`:
- Around line 269-273: selectSuggestion may call
aegisSuggestionWatcher.applyAISuggestion with currentSuggestion that is a scalar
string when fieldName === 'components', which can violate the component's model
type (expects string[] | null | undefined); update selectSuggestion (and other
places noted: the block around lines handling components, and where
currentSuggestion is applied) to detect when fieldName === 'components' and
currentSuggestion is a string and instead pass an array (e.g., wrap the string
in [currentSuggestion]) or otherwise convert to the expected string[] shape
before calling aegisSuggestionWatcher.applyAISuggestion so the modelValue
contract is preserved.
🪄 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: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: 7d37f425-80c7-427e-a297-d7036a3a0318
⛔ Files ignored due to path filters (2)
src/components/Aegis/__tests__/__snapshots__/AegisComponentActions.spec.ts.snapis excluded by!**/*.snapsrc/views/__tests__/__snapshots__/FlawCreateView.spec.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (16)
CHANGELOG.mdsrc/components/Aegis/AegisActions.vuesrc/components/Aegis/AegisComponentActions.vuesrc/components/Aegis/__tests__/AegisComponentActions.spec.tssrc/components/Aegis/__tests__/AegisCvssActions.spec.tssrc/components/Aegis/__tests__/AegisCweActions.spec.tssrc/components/Aegis/__tests__/AegisImpactActions.spec.tssrc/components/Aegis/__tests__/AegisMitigationActions.spec.tssrc/components/Aegis/__tests__/AegisStatementActions.spec.tssrc/components/FlawForm/FlawForm.vuesrc/composables/__tests__/useAegisSuggestion.spec.tssrc/composables/aegis/__tests__/useAegisSuggestComponents.spec.tssrc/composables/aegis/useAISuggestionsWatcher.tssrc/composables/aegis/useAegisSuggestComponents.tssrc/composables/aegis/useAegisSuggestion.tssrc/types/aegisAI.ts
✅ Files skipped from review due to trivial changes (2)
- CHANGELOG.md
- src/composables/tests/useAegisSuggestion.spec.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- src/types/aegisAI.ts
- src/components/Aegis/tests/AegisComponentActions.spec.ts
- src/components/FlawForm/FlawForm.vue
- src/composables/aegis/tests/useAegisSuggestComponents.spec.ts
- src/components/Aegis/AegisActions.vue
- src/composables/aegis/useAegisSuggestComponents.ts
42b2e8c to
b0313c2
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/composables/aegis/useAegisSuggestion.ts (1)
287-291:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
componentssuggestions are flattened into per-item suggestions instead of one grouped suggestion.For
fieldName === 'components', Line 290 returnsstring[]directly. This makescurrentSuggestionresolve to a single component string, so selection/feedback paths can operate on one item rather than the full suggested component set.Proposed fix
const allSuggestions = computed(() => { const fieldValue = details.value?.[detailsField]; if (fieldValue === null || fieldValue === undefined) return []; - return Array.isArray(fieldValue) ? fieldValue : [fieldValue]; + if (fieldName === 'components') { + return Array.isArray(fieldValue) ? [fieldValue] : []; + } + return Array.isArray(fieldValue) ? fieldValue : [fieldValue]; });Also applies to: 293-307
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/composables/aegis/useAegisSuggestion.ts` around lines 287 - 291, The computed allSuggestions currently flattens the components array into individual string suggestions, causing currentSuggestion to treat each component separately; change the logic so when detailsField (or fieldName) === 'components' you do not flatten arrays — if fieldValue is an array return [fieldValue] (a single grouped suggestion) instead of fieldValue, and apply the same grouping change in the similar block at lines 293-307 so selection/feedback operate on the whole suggested component set rather than individual items.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/composables/aegis/useAegisSuggestComponents.ts`:
- Around line 144-159: The sendFeedback function currently sets
userFeedbackSent.value = true unconditionally, so failures from sendFeedbackApi
block retries; modify sendFeedback (the async function sendFeedback in
useAegisSuggestComponents.ts) to only mark userFeedbackSent true when
sendFeedbackApi succeeds: call sendFeedbackApi inside a try/catch (or inspect
its returned result), set userFeedbackSent.value = true only on success, and
handle/log or rethrow errors in the catch so the UI can allow retries instead of
permanently marking feedback as sent.
---
Outside diff comments:
In `@src/composables/aegis/useAegisSuggestion.ts`:
- Around line 287-291: The computed allSuggestions currently flattens the
components array into individual string suggestions, causing currentSuggestion
to treat each component separately; change the logic so when detailsField (or
fieldName) === 'components' you do not flatten arrays — if fieldValue is an
array return [fieldValue] (a single grouped suggestion) instead of fieldValue,
and apply the same grouping change in the similar block at lines 293-307 so
selection/feedback operate on the whole suggested component set rather than
individual items.
🪄 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: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: 6d4c4a94-fb3e-4476-bcda-03325d8d9d18
⛔ Files ignored due to path filters (3)
src/components/Aegis/__tests__/__snapshots__/AegisComponentActions.spec.ts.snapis excluded by!**/*.snapsrc/components/__tests__/__snapshots__/FlawForm.spec.ts.snapis excluded by!**/*.snapsrc/views/__tests__/__snapshots__/FlawCreateView.spec.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (16)
CHANGELOG.mdsrc/components/Aegis/AegisActions.vuesrc/components/Aegis/AegisComponentActions.vuesrc/components/Aegis/__tests__/AegisComponentActions.spec.tssrc/components/Aegis/__tests__/AegisCvssActions.spec.tssrc/components/Aegis/__tests__/AegisCweActions.spec.tssrc/components/Aegis/__tests__/AegisImpactActions.spec.tssrc/components/Aegis/__tests__/AegisMitigationActions.spec.tssrc/components/Aegis/__tests__/AegisStatementActions.spec.tssrc/components/FlawForm/FlawForm.vuesrc/composables/__tests__/useAegisSuggestion.spec.tssrc/composables/aegis/__tests__/useAegisSuggestComponents.spec.tssrc/composables/aegis/useAISuggestionsWatcher.tssrc/composables/aegis/useAegisSuggestComponents.tssrc/composables/aegis/useAegisSuggestion.tssrc/types/aegisAI.ts
✅ Files skipped from review due to trivial changes (3)
- CHANGELOG.md
- src/composables/tests/useAegisSuggestion.spec.ts
- src/components/Aegis/tests/AegisCweActions.spec.ts
🚧 Files skipped from review as they are similar to previous changes (10)
- src/components/Aegis/tests/AegisImpactActions.spec.ts
- src/components/Aegis/tests/AegisStatementActions.spec.ts
- src/components/Aegis/tests/AegisMitigationActions.spec.ts
- src/components/Aegis/AegisActions.vue
- src/components/Aegis/tests/AegisCvssActions.spec.ts
- src/composables/aegis/tests/useAegisSuggestComponents.spec.ts
- src/components/FlawForm/FlawForm.vue
- src/components/Aegis/tests/AegisComponentActions.spec.ts
- src/types/aegisAI.ts
- src/components/Aegis/AegisComponentActions.vue
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
b0313c2 to
5a76eb6
Compare
Checklist:
Summary
Add manual Source Component field suggestions.
Changes
useAegisSuggestComponentscomposableAegisComponentActionsfollowing existing Aegis patternsConsiderations
aiComponentSuggestionsfeature flag to be enabled