Skip to content

Commit 7f873aa

Browse files
github-actions[bot]Marfuenclaude
authored
feat: improve AI policy editor, better UI/UX and smarter
* docs: add per-hunk feedback design spec for suggested changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add per-hunk feedback UI to proposed changes card Add pencil icon button to the accept/reject pill that opens an inline text input for per-hunk AI feedback. Submitting sends contextual feedback through the existing chat, shows a shimmer loading state for the targeted hunk, and remaps decisions when the proposal changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: enhance policy editor with improved proposal handling and UI updates - Refactor `getLatestProposedPolicy` to `getLatestCompletedProposal` for better tracking of proposals across the entire conversation. - Update `PolicyContentManager` to utilize the new proposal fetching logic and manage proposal states more effectively. - Revamp `PolicyAiAssistant` UI to improve user interaction and feedback display. - Introduce confirmation for applying all changes in `ProposedChangesCard`, ensuring user intent is clear before executing bulk actions. - Update `.gitignore` to exclude new directories related to superpowers documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: filter no-change hunks, merge skip blocks, and improve AI prompt - Filter out hunks with only whitespace-only changes from the diff view - Merge adjacent skip blocks and no-change hunks into a single "Show N unchanged lines" section - Count changes by reviewable sections (hunks) instead of individual lines - Reject All now marks all hunks as rejected instead of clearing to pending - Strengthen system prompt to preserve unchanged text verbatim Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add inline suggestion mode design spec Spec for replacing the separate ProposedChangesCard with inline TipTap decorations rendered directly in the policy editor. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(policy-editor): add inline suggestion types, position map, and range computation Add shared types for inline suggestions (DiffSegment, SuggestionRange, PositionMap), a position map builder that maps ProseMirror doc nodes to markdown line numbers, and a suggestion range computer that diffs markdown and produces positioned ranges with word-level diff segments. Includes comprehensive tests for both modules. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(editor): add SuggestionsExtension and thread props through editor chain Add TipTap ProseMirror plugin for inline suggestion decorations (modify, insert, delete) with gutter widgets for accept/reject/feedback actions. Extend Editor, AdvancedEditor, and PolicyEditor with additionalExtensions and onEditorReady props. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(policy-editor): integrate inline suggestions into PolicyDetails Replace ProposedChangesCard with inline editor suggestions using useSuggestions hook and SuggestionsTopBar. Remove diff/patch utility functions (createGitPatch, applySelectedHunks, convertContentToMarkdown) that are no longer needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(suggestions): remove ProposedChangesCard and unused utilities Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test(suggestions): add unit tests for useSuggestions hook Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(suggestions): add remaining inline suggestion files Add useSuggestions hook, SuggestionsTopBar component, suggestion CSS styles, implementation plan doc, and fix PolicyDetails tests for new inline suggestions dependencies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(suggestions): cursor-style navigation, bolder styling, render new sections as rich content - add prev/next navigation with keyboard shortcuts (F7/Shift+F7) - accept/reject current change from top bar (Cmd+Shift+Enter/Backspace) - focused change highlighting with extra emphasis - render new section widgets as proper DOM nodes (headings, lists, paragraphs) instead of raw markdown text - bolder red/green diff colors with underlines and strikethroughs - dark mode support for suggestion styles - add left padding to editor when suggestions active for gutter visibility Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(suggestions): rewrite decoration building to walk document tree The previous approach used character offsets from diff segments as ProseMirror positions, but PM positions include structural tokens (open/close tags for blocks), so positions diverged for multi-block hunks. Decorations were created but not rendered. New approach: - Use doc.descendants() to find text blocks overlapping each range - Apply Decoration.node() to each block individually (always works) - Only attempt inline word-level diffs for single-block modifications - Render new section widgets using DOMSerializer for proper styling Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(suggestions): lock editor during review, fix gutter placement - Make editor non-editable while suggestions are pending via ProseMirror editable prop — prevents content changes during review - Place gutter widgets inside the first text block of each range (pos + 1) so they render correctly for list items and nested blocks Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(suggestions): remove left margin, show modify as green+red pair - Remove has-suggestions padding that pushed content right - Gutter buttons now inline (no absolute positioning/margin needed) - Modify hunks now show as green block (proposed) above red strikethrough block (original) — making it clear they're one change - Accepting replaces old (red) with new (green) - Remove unused suggestion-modified class Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(suggestions): fix bold text in new sections, place widgets at top level - Reset font-weight to normal in .suggestion-new-section so only headings inside are bold, not body text and list items - Place insertion widgets and gutter buttons at depth-1 (doc child) position so they render outside nested structures (lists, blockquotes) and don't inherit parent element styling Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(suggestions): merge overlapping ranges, remove inline gutter buttons - Merge overlapping/adjacent hunks that resolve to the same doc position into a single modify range — prevents duplicate button sets - Remove inline gutter buttons entirely — accept/reject is handled by the sticky top bar with navigation (cleaner, no layout issues) - Remove gutter CSS and callback plumbing (no longer needed) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(suggestions): clean up unused extension options Remove onAccept/onReject/onFeedback from SuggestionsExtensionOptions since accept/reject is handled entirely by the top bar. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(suggestions): auto-scroll to first change when suggestions arrive Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(suggestions): enhance suggestions functionality with action bars and improved UI - Introduced action bars for accepting, rejecting, and providing feedback on suggestions. - Updated the suggestions top bar for better navigation and user interaction. - Enhanced styling for suggestion elements, including new CSS for action buttons and suggestion groups. - Improved the logic for scrolling to the first change and handling suggestion states. - Added support for showing/hiding toolbars based on suggestion activity. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(suggestions): enhance policy editor with feedback input and improved suggestion handling - Added a new SuggestionFeedbackInput component for inline feedback on suggestions. - Updated PolicyContentManager to handle editing and feedback submission for suggestions. - Enhanced useSuggestions hook to manage editing state and loading indicators. - Improved buildPositionMap and computeSuggestionRanges functions for better handling of list items and content normalization. - Updated styles for suggestion elements to improve user experience. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: resolve merge conflicts and clean up imports - Fix @comp/ui → @trycompai/ui import paths after merge - Remove duplicate @trycompai/email entries in tsconfig.json - Suppress Node.js deprecation warnings in dev script Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(policy-editor): enhance AI assistant and suggestions functionality - Adjusted media query for wide desktop view to 1280px. - Integrated stop functionality for AI assistant chat. - Improved layout for AI assistant and suggestions top bar. - Enhanced scrolling behavior for suggestion ranges. - Added history tracking for suggestion ranges to support undo functionality. - Updated markdown parsing to ensure accurate rendering of proposed content. This update aims to improve user experience in the policy editor by refining the AI assistant's interaction and enhancing the suggestions management system. * feat(policy-editor): improve suggestion system, chat UX, and RBAC - Rewrite buildPositionMap with two-pass approach for accurate line-to-position mapping - Extend delete ranges to next heading boundary for full section deletions - Merge adjacent diff hunks within 20 positions to prevent split deletions - Use single markdown parser (markdownToTipTapJSON) for both preview and accept - Move AI tools from direct DB access to API calls with cookie forwarding for RBAC - Strip previous proposePolicy content from conversation history to prevent reuse - Add multi-step tool calling with stopWhen(stepCountIs(5)) - Add thinking indicator, stop button, and tool loading states to chat UI - User messages render as right-aligned bubbles, compact tool cards - Auto-dismiss proposals on active→inactive transition - Undo support: Cmd+Z restores previous suggestion ranges - Lock editor during pending suggestions, restore original editable state - Side panel: sticky positioning, viewport-relative height, internal scroll - Editor bottom shadow instead of border for visual end marker - Comprehensive tests: 82 tests for position mapping and range computation, 27 tests for markdown parser, 55 tests for suggestion hook lifecycle Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Mariano Fuentes <marfuen98@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 37dc0a4 commit 7f873aa

27 files changed

Lines changed: 5681 additions & 412 deletions

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ node_modules
66
.pnp.js
77

88
.idea/
9+
.superpowers/
10+
docs/superpowers/
911
# testing
1012
coverage
1113

apps/app/next.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const config: NextConfig = {
4848
'@trycompai/db',
4949
'@prisma/client',
5050
'@trycompai/design-system',
51+
'@trycompai/ui',
5152
'@carbon/icons-react',
5253
'@trycompai/company',
5354
],

apps/app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@
189189
"db:getschema": "node ../../packages/db/scripts/combine-schemas.js && cp ../../packages/db/dist/schema.prisma prisma/schema.prisma",
190190
"db:migrate": "cd ../../packages/db && bunx prisma migrate dev && cd ../../apps/app",
191191
"deploy:trigger-prod": "npx trigger.dev@4.0.6 deploy",
192-
"dev": "bun i && bunx concurrently --kill-others --names \"next,trigger\" --prefix-colors \"yellow,blue\" \"next dev --turbo -p 3000\" \"trigger dev\"",
192+
"dev": "bun i && bunx concurrently --kill-others --names \"next,trigger\" --prefix-colors \"yellow,blue\" \"NODE_OPTIONS='--no-deprecation' next dev --turbo -p 3000\" \"NODE_OPTIONS='--no-deprecation' trigger dev\"",
193193
"lint": "eslint . && prettier --check .",
194194
"prebuild": "bun run db:generate",
195195
"postinstall": "prisma generate --schema=./prisma/schema.prisma || exit 0",

apps/app/src/app/(app)/[orgId]/policies/[policyId]/editor/components/PolicyDetails.test.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@ import {
88
} from '@/test-utils/mocks/permissions';
99
import { PolicyStatus } from '@db';
1010

11+
// Mock matchMedia for useMediaQuery
12+
Object.defineProperty(window, 'matchMedia', {
13+
writable: true,
14+
value: vi.fn().mockImplementation((query: string) => ({
15+
matches: false,
16+
media: query,
17+
onchange: null,
18+
addListener: vi.fn(),
19+
removeListener: vi.fn(),
20+
addEventListener: vi.fn(),
21+
removeEventListener: vi.fn(),
22+
dispatchEvent: vi.fn(),
23+
})),
24+
});
25+
1126
// Mock usePermissions
1227
vi.mock('@/hooks/use-permissions', () => ({
1328
usePermissions: () => ({
@@ -86,6 +101,27 @@ vi.mock('diff', () => ({
86101
// Mock editor CSS import
87102
vi.mock('@/styles/editor.css', () => ({}));
88103

104+
// Mock useSuggestions hook
105+
vi.mock('../hooks/use-suggestions', () => ({
106+
useSuggestions: () => ({
107+
ranges: [],
108+
activeCount: 0,
109+
totalCount: 0,
110+
currentIndex: 0,
111+
accept: vi.fn(),
112+
reject: vi.fn(),
113+
acceptCurrent: vi.fn(),
114+
rejectCurrent: vi.fn(),
115+
acceptAll: vi.fn(),
116+
rejectAll: vi.fn(),
117+
dismissAll: vi.fn(),
118+
giveFeedback: vi.fn(),
119+
goToNext: vi.fn(),
120+
goToPrev: vi.fn(),
121+
isActive: false,
122+
}),
123+
}));
124+
89125
// Mock PolicyEditor
90126
vi.mock('@/components/editor/policy-editor', () => ({
91127
PolicyEditor: ({
@@ -98,6 +134,8 @@ vi.mock('@/components/editor/policy-editor', () => ({
98134
// Mock editor utils
99135
vi.mock('@trycompai/ui/editor', () => ({
100136
validateAndFixTipTapContent: (content: unknown) => ({ content }),
137+
SuggestionsExtension: { configure: () => ({}) },
138+
suggestionsPluginKey: { key: 'suggestions$' },
101139
}));
102140

103141
// Mock DiffViewer

0 commit comments

Comments
 (0)