mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
Implement a comprehensive diff viewing system that allows users to review and approve/reject file changes before they're applied. The system includes event-driven architecture for managing diff lifecycle and integrates diff2html for rich visual diffs. Key changes: - Add DiffService for managing diff approval workflow with accept/reject/suggest actions - Create EventService for type-safe event handling (DiffOpened/DiffClosed) - Add DiffView component with diff2html integration for visual diff rendering - Modify VaultService to propose changes and require confirmation before file operations - Update FileSystemService to support optional confirmation for write operations - Add Event enum for centralized event type definitions - Import custom styles and diff2html styles for proper diff rendering - Update ConversationContent validation to support optional toolId field - Remove FileManager from dependency injection (now accessed directly from app) - Update .gitignore to track styles.css instead of main.css
400 lines
No EOL
11 KiB
CSS
400 lines
No EOL
11 KiB
CSS
/**
|
|
* Diff2html Obsidian Theme Override
|
|
*
|
|
* This stylesheet overrides diff2html's default styling to use Obsidian's CSS variables
|
|
*
|
|
*/
|
|
|
|
/* ========================================
|
|
ROOT VARIABLE OVERRIDES - LIGHT THEME
|
|
======================================== */
|
|
|
|
:root {
|
|
/* Background colors */
|
|
--d2h-bg-color: var(--background-primary);
|
|
--d2h-file-header-bg-color: var(--background-secondary);
|
|
--d2h-file-diff-wrapper-bg-color: var(--background-primary);
|
|
--d2h-file-list-wrapper-bg-color: var(--background-secondary);
|
|
--d2h-file-list-header-bg-color: var(--background-secondary-alt);
|
|
|
|
/* Border colors */
|
|
--d2h-border-color: var(--background-modifier-border);
|
|
--d2h-file-border-color: var(--background-modifier-border);
|
|
--d2h-line-border-color: var(--background-modifier-border);
|
|
|
|
/* Text colors */
|
|
--d2h-text-color: var(--text-normal);
|
|
--d2h-muted-text-color: var(--text-muted);
|
|
--d2h-file-name-color: var(--text-normal);
|
|
--d2h-file-stats-color: var(--text-muted);
|
|
--d2h-line-number-color: var(--text-muted);
|
|
|
|
/* Insertion colors (additions) */
|
|
--d2h-ins-bg-color: color-mix(in srgb, var(--color-green) 15%, var(--background-primary));
|
|
--d2h-ins-label-color: var(--color-green);
|
|
--d2h-ins-highlight-bg-color: color-mix(in srgb, var(--color-green) 30%, var(--background-primary));
|
|
--d2h-ins-border-color: color-mix(in srgb, var(--color-green) 40%, var(--background-modifier-border));
|
|
|
|
/* Deletion colors (removals) */
|
|
--d2h-del-bg-color: color-mix(in srgb, var(--color-red) 15%, var(--background-primary));
|
|
--d2h-del-label-color: var(--color-red);
|
|
--d2h-del-highlight-bg-color: color-mix(in srgb, var(--color-red) 30%, var(--background-primary));
|
|
--d2h-del-border-color: color-mix(in srgb, var(--color-red) 40%, var(--background-modifier-border));
|
|
|
|
/* Change/modification colors */
|
|
--d2h-change-bg-color: color-mix(in srgb, var(--color-yellow) 15%, var(--background-primary));
|
|
--d2h-change-label-color: var(--color-yellow);
|
|
|
|
/* Info colors */
|
|
--d2h-info-bg-color: color-mix(in srgb, var(--color-cyan) 10%, var(--background-secondary));
|
|
--d2h-info-text-color: var(--text-muted);
|
|
|
|
/* Link colors */
|
|
--d2h-link-color: var(--interactive-accent);
|
|
--d2h-link-hover-color: var(--interactive-accent-hover);
|
|
|
|
/* Code colors */
|
|
--d2h-code-bg-color: var(--background-primary-alt);
|
|
--d2h-code-text-color: var(--text-normal);
|
|
|
|
/* Selection and hover */
|
|
--d2h-hover-bg-color: var(--background-modifier-hover);
|
|
--d2h-selected-bg-color: var(--background-modifier-active-hover);
|
|
}
|
|
|
|
/* ========================================
|
|
DARK THEME OVERRIDES
|
|
======================================== */
|
|
|
|
/* Dark theme with explicit class */
|
|
.d2h-dark-color-scheme,
|
|
.theme-dark {
|
|
/* Background colors */
|
|
--d2h-dark-bg-color: var(--background-primary);
|
|
--d2h-dark-file-header-bg-color: var(--background-secondary);
|
|
--d2h-dark-file-diff-wrapper-bg-color: var(--background-primary);
|
|
--d2h-dark-file-list-wrapper-bg-color: var(--background-secondary);
|
|
--d2h-dark-file-list-header-bg-color: var(--background-secondary-alt);
|
|
|
|
/* Border colors */
|
|
--d2h-dark-border-color: var(--background-modifier-border);
|
|
--d2h-dark-file-border-color: var(--background-modifier-border);
|
|
--d2h-dark-line-border-color: var(--background-modifier-border);
|
|
|
|
/* Text colors */
|
|
--d2h-dark-text-color: var(--text-normal);
|
|
--d2h-dark-muted-text-color: var(--text-muted);
|
|
--d2h-dark-file-name-color: var(--text-normal);
|
|
--d2h-dark-file-stats-color: var(--text-muted);
|
|
--d2h-dark-line-number-color: var(--text-muted);
|
|
|
|
/* Insertion colors (additions) */
|
|
--d2h-dark-ins-bg-color: color-mix(in srgb, var(--color-green) 15%, var(--background-primary));
|
|
--d2h-dark-ins-label-color: color-mix(in srgb, var(--color-green) 120%, white);
|
|
--d2h-dark-ins-highlight-bg-color: color-mix(in srgb, var(--color-green) 30%, var(--background-primary));
|
|
--d2h-dark-ins-border-color: color-mix(in srgb, var(--color-green) 50%, var(--background-modifier-border));
|
|
|
|
/* Deletion colors (removals) */
|
|
--d2h-dark-del-bg-color: color-mix(in srgb, var(--color-red) 20%, var(--background-primary));
|
|
--d2h-dark-del-label-color: color-mix(in srgb, var(--color-red) 120%, white);
|
|
--d2h-dark-del-highlight-bg-color: color-mix(in srgb, var(--color-red) 35%, var(--background-primary));
|
|
--d2h-dark-del-border-color: color-mix(in srgb, var(--color-red) 50%, var(--background-modifier-border));
|
|
|
|
/* Change/modification colors */
|
|
--d2h-dark-change-bg-color: color-mix(in srgb, var(--color-yellow) 20%, var(--background-primary));
|
|
--d2h-dark-change-label-color: color-mix(in srgb, var(--color-yellow) 120%, white);
|
|
|
|
/* Info colors */
|
|
--d2h-dark-info-bg-color: color-mix(in srgb, var(--color-cyan) 15%, var(--background-secondary));
|
|
--d2h-dark-info-text-color: var(--text-muted);
|
|
|
|
/* Link colors */
|
|
--d2h-dark-link-color: var(--interactive-accent);
|
|
--d2h-dark-link-hover-color: var(--interactive-accent-hover);
|
|
|
|
/* Code colors */
|
|
--d2h-dark-code-bg-color: var(--background-primary-alt);
|
|
--d2h-dark-code-text-color: var(--text-normal);
|
|
|
|
/* Selection and hover */
|
|
--d2h-dark-hover-bg-color: var(--background-modifier-hover);
|
|
--d2h-dark-selected-bg-color: var(--background-modifier-active-hover);
|
|
}
|
|
|
|
/* Auto theme - follows system preference */
|
|
@media (prefers-color-scheme: dark) {
|
|
.d2h-auto-color-scheme {
|
|
/* Apply dark theme variables */
|
|
--d2h-bg-color: var(--d2h-dark-bg-color);
|
|
--d2h-file-header-bg-color: var(--d2h-dark-file-header-bg-color);
|
|
--d2h-border-color: var(--d2h-dark-border-color);
|
|
--d2h-text-color: var(--d2h-dark-text-color);
|
|
--d2h-ins-bg-color: var(--d2h-dark-ins-bg-color);
|
|
--d2h-ins-label-color: var(--d2h-dark-ins-label-color);
|
|
--d2h-ins-highlight-bg-color: var(--d2h-dark-ins-highlight-bg-color);
|
|
--d2h-del-bg-color: var(--d2h-dark-del-bg-color);
|
|
--d2h-del-label-color: var(--d2h-dark-del-label-color);
|
|
--d2h-del-highlight-bg-color: var(--d2h-dark-del-highlight-bg-color);
|
|
}
|
|
}
|
|
|
|
/* ========================================
|
|
COMPONENT-SPECIFIC OVERRIDES
|
|
======================================== */
|
|
|
|
/* File wrapper */
|
|
.d2h-wrapper {
|
|
background-color: var(--background-primary);
|
|
color: var(--text-normal);
|
|
font-family: var(--font-interface);
|
|
font-size: var(--font-ui-small);
|
|
}
|
|
|
|
/* File header */
|
|
.d2h-file-header {
|
|
background-color: var(--background-secondary);
|
|
border-color: var(--background-modifier-border);
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.d2h-file-name {
|
|
color: var(--text-normal);
|
|
font-family: var(--font-monospace);
|
|
}
|
|
|
|
.d2h-file-stats {
|
|
color: var(--text-muted);
|
|
font-size: var(--font-ui-smaller);
|
|
}
|
|
|
|
/* Code lines */
|
|
.d2h-code-line {
|
|
color: var(--text-normal);
|
|
font-family: var(--font-monospace);
|
|
font-size: var(--font-ui-small);
|
|
}
|
|
|
|
.d2h-code-line-ctn {
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.d2h-code-line-prefix {
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
/* Line numbers */
|
|
.d2h-code-linenumber {
|
|
background-color: var(--background-secondary-alt);
|
|
color: var(--text-muted);
|
|
border-color: var(--background-modifier-border);
|
|
}
|
|
|
|
/* Insertion (added) lines */
|
|
.d2h-ins {
|
|
background-color: var(--d2h-ins-bg-color);
|
|
}
|
|
|
|
.d2h-ins .d2h-code-line-prefix {
|
|
color: var(--d2h-ins-label-color);
|
|
}
|
|
|
|
.d2h-ins .d2h-code-line-ctn {
|
|
background-color: transparent;
|
|
}
|
|
|
|
.d2h-ins.d2h-change {
|
|
background-color: var(--d2h-change-bg-color);
|
|
}
|
|
|
|
/* Deletion (removed) lines */
|
|
.d2h-del {
|
|
background-color: var(--d2h-del-bg-color);
|
|
}
|
|
|
|
.d2h-del .d2h-code-line-prefix {
|
|
color: var(--d2h-del-label-color);
|
|
}
|
|
|
|
.d2h-del .d2h-code-line-ctn {
|
|
background-color: transparent;
|
|
}
|
|
|
|
.d2h-del.d2h-change {
|
|
background-color: var(--d2h-change-bg-color);
|
|
}
|
|
|
|
/* Word-level highlighting */
|
|
.d2h-ins .d2h-change-highlight {
|
|
background-color: var(--d2h-ins-highlight-bg-color);
|
|
border-radius: 2px;
|
|
padding: 0 2px;
|
|
}
|
|
|
|
.d2h-del .d2h-change-highlight {
|
|
background-color: var(--d2h-del-highlight-bg-color);
|
|
border-radius: 2px;
|
|
padding: 0 2px;
|
|
}
|
|
|
|
/* Context (unchanged) lines */
|
|
.d2h-cxt {
|
|
background-color: var(--background-primary);
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
/* Info lines */
|
|
.d2h-info {
|
|
background-color: var(--d2h-info-bg-color);
|
|
color: var(--d2h-info-text-color);
|
|
border-color: var(--background-modifier-border);
|
|
}
|
|
|
|
/* File list */
|
|
.d2h-file-list-wrapper {
|
|
background-color: var(--background-secondary);
|
|
border-color: var(--background-modifier-border);
|
|
}
|
|
|
|
.d2h-file-list-header {
|
|
background-color: var(--background-secondary-alt);
|
|
border-color: var(--background-modifier-border);
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.d2h-file-list-line {
|
|
border-color: var(--background-modifier-border);
|
|
}
|
|
|
|
.d2h-file-list-line:hover {
|
|
background-color: var(--background-modifier-hover);
|
|
}
|
|
|
|
/* Links */
|
|
.d2h-file-name-link,
|
|
.d2h-file-link {
|
|
color: var(--interactive-accent);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.d2h-file-name-link:hover,
|
|
.d2h-file-link:hover {
|
|
color: var(--interactive-accent-hover);
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* Tag/label styling */
|
|
.d2h-tag {
|
|
background-color: var(--background-modifier-border);
|
|
color: var(--text-normal);
|
|
border-radius: var(--radius-s);
|
|
padding: 2px 6px;
|
|
font-size: var(--font-ui-smaller);
|
|
}
|
|
|
|
/* Diff table */
|
|
.d2h-diff-table {
|
|
border-color: var(--background-modifier-border);
|
|
background-color: var(--background-primary);
|
|
}
|
|
|
|
/* Empty placeholder */
|
|
.d2h-empty-placeholder {
|
|
color: var(--text-faint);
|
|
background-color: var(--background-secondary);
|
|
}
|
|
|
|
/* ========================================
|
|
OBSIDIAN-SPECIFIC ENHANCEMENTS
|
|
======================================== */
|
|
|
|
/* Integrate with Obsidian's scrollbar styling */
|
|
.d2h-wrapper::-webkit-scrollbar {
|
|
width: var(--scrollbar-width);
|
|
}
|
|
|
|
.d2h-wrapper::-webkit-scrollbar-track {
|
|
background: var(--background-primary);
|
|
}
|
|
|
|
.d2h-wrapper::-webkit-scrollbar-thumb {
|
|
background: var(--scrollbar-thumb-bg);
|
|
border-radius: var(--radius-s);
|
|
}
|
|
|
|
.d2h-wrapper::-webkit-scrollbar-thumb:hover {
|
|
background: var(--scrollbar-active-thumb-bg);
|
|
}
|
|
|
|
/* Match Obsidian's border radius */
|
|
.d2h-file-wrapper {
|
|
border-radius: var(--radius-m);
|
|
}
|
|
|
|
.d2h-file-header {
|
|
border-top-left-radius: var(--radius-m);
|
|
border-top-right-radius: var(--radius-m);
|
|
}
|
|
|
|
/* Ensure proper contrast in Obsidian's theme */
|
|
.theme-light .d2h-code-line,
|
|
.theme-light .d2h-code-linenumber {
|
|
border-color: var(--background-modifier-border);
|
|
}
|
|
|
|
.theme-dark .d2h-code-line,
|
|
.theme-dark .d2h-code-linenumber {
|
|
border-color: var(--background-modifier-border);
|
|
}
|
|
|
|
/* Responsive adjustments for mobile */
|
|
.is-mobile .d2h-wrapper {
|
|
font-size: var(--font-ui-smaller);
|
|
}
|
|
|
|
.is-mobile .d2h-code-line {
|
|
font-size: var(--font-ui-smaller);
|
|
padding: var(--size-2-1) var(--size-2-2);
|
|
}
|
|
|
|
/* ========================================
|
|
ACCESSIBILITY IMPROVEMENTS
|
|
======================================== */
|
|
|
|
/* Ensure focus states are visible */
|
|
.d2h-file-list-line:focus,
|
|
.d2h-file-name-link:focus {
|
|
outline: 2px solid var(--interactive-accent);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* Improve contrast for line numbers */
|
|
.d2h-code-linenumber {
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.d2h-code-line:hover .d2h-code-linenumber {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* ========================================
|
|
PRINT STYLES
|
|
======================================== */
|
|
|
|
@media print {
|
|
.d2h-wrapper {
|
|
background: white;
|
|
color: black;
|
|
}
|
|
|
|
.d2h-ins {
|
|
background-color: #d4ffd4 !important;
|
|
}
|
|
|
|
.d2h-del {
|
|
background-color: #ffd4d4 !important;
|
|
}
|
|
|
|
.d2h-code-linenumber {
|
|
background-color: #f5f5f5 !important;
|
|
}
|
|
} |