feat(discovery): enhance discovery index reading and issue exporting

- Improved the reading of the discovery index by adding a fallback mechanism to scan directories for discovery folders if the index.json is invalid or missing.
- Added sorting of discoveries by creation time in descending order.
- Enhanced the `appendToIssuesJsonl` function to include deduplication logic for issues based on ID and source finding ID.
- Updated the discovery route handler to reflect the number of issues added and skipped during export.
- Introduced UI elements for selecting and deselecting findings in the dashboard.
- Added CSS styles for exported findings and action buttons.
- Implemented search functionality for filtering findings based on title, file, and description.
- Added internationalization support for new UI elements.
- Created scripts for automated API extraction from various project types, including FastAPI and TypeScript.
- Documented the API extraction process and library bundling instructions.
This commit is contained in:
catlog22
2025-12-28 19:27:34 +08:00
parent 3ef1e54412
commit 169f218f7a
18 changed files with 1602 additions and 612 deletions

View File

@@ -449,14 +449,65 @@ body {
margin-bottom: var(--spacing-md);
}
/* Lists - Enhanced Styling */
.tiddler-content ul,
.tiddler-content ol {
margin-bottom: var(--spacing-md);
padding-left: var(--spacing-lg);
margin: var(--spacing-md) 0;
padding-left: var(--spacing-xl);
}
.tiddler-content li {
margin-bottom: var(--spacing-xs);
.tiddler-content ul {
list-style: none;
}
.tiddler-content ul > li {
position: relative;
margin-bottom: var(--spacing-sm);
padding-left: 8px;
}
.tiddler-content ul > li::before {
content: "•";
position: absolute;
left: -16px;
color: var(--accent-color);
font-weight: bold;
}
.tiddler-content ol {
list-style: none;
counter-reset: item;
}
.tiddler-content ol > li {
position: relative;
margin-bottom: var(--spacing-sm);
padding-left: 8px;
counter-increment: item;
}
.tiddler-content ol > li::before {
content: counter(item) ".";
position: absolute;
left: -24px;
color: var(--accent-color);
font-weight: 600;
}
/* Nested lists */
.tiddler-content ul ul,
.tiddler-content ol ol,
.tiddler-content ul ol,
.tiddler-content ol ul {
margin: var(--spacing-xs) 0;
}
.tiddler-content ul ul > li::before {
content: "◦";
}
.tiddler-content ul ul ul > li::before {
content: "▪";
}
.tiddler-content a {
@@ -468,70 +519,112 @@ body {
text-decoration: underline;
}
/* Code */
/* Inline Code - Red Highlight */
.tiddler-content code {
font-family: var(--font-family-mono);
font-size: 0.9em;
font-size: 0.875em;
padding: 2px 6px;
background-color: var(--bg-tertiary);
background-color: #fff5f5;
color: #c92a2a;
border-radius: 4px;
border: 1px solid #ffc9c9;
}
/* Code Blocks - Dark Background */
.tiddler-content pre {
position: relative;
margin-bottom: var(--spacing-md);
padding: var(--spacing-md);
background-color: #1e1e1e;
margin: var(--spacing-md) 0;
padding: 0;
background-color: #1e2128;
border-radius: 8px;
overflow-x: auto;
overflow: hidden;
border: 1px solid #3d4450;
}
.tiddler-content pre::before {
content: attr(data-language);
display: block;
padding: 8px 16px;
background-color: #2d333b;
color: #8b949e;
font-size: 0.75rem;
font-family: var(--font-family);
text-transform: uppercase;
letter-spacing: 0.05em;
border-bottom: 1px solid #3d4450;
}
.tiddler-content pre code {
padding: 0;
display: block;
padding: var(--spacing-md);
background: none;
color: #d4d4d4;
color: #e6edf3;
font-size: var(--font-size-sm);
line-height: 1.6;
overflow-x: auto;
border: none;
}
.copy-code-btn {
position: absolute;
top: var(--spacing-sm);
right: var(--spacing-sm);
padding: var(--spacing-xs) var(--spacing-sm);
font-size: 0.75rem;
background-color: var(--bg-tertiary);
border: none;
top: 6px;
right: 12px;
padding: 4px 10px;
font-size: 0.7rem;
background-color: #3d4450;
color: #8b949e;
border: 1px solid #4d5566;
border-radius: 4px;
cursor: pointer;
opacity: 0;
transition: opacity var(--transition-fast);
transition: all var(--transition-fast);
}
.copy-code-btn:hover {
background-color: #4d5566;
color: #e6edf3;
}
.tiddler-content pre:hover .copy-code-btn {
opacity: 1;
}
/* Tables */
/* Tables - Blue Header Style */
.tiddler-content table {
width: 100%;
margin-bottom: var(--spacing-md);
margin: var(--spacing-md) 0;
border-collapse: collapse;
}
.tiddler-content th,
.tiddler-content td {
padding: var(--spacing-sm) var(--spacing-md);
border: 1px solid var(--border-color);
text-align: left;
border: 1px solid #dee2e6;
border-radius: 8px;
overflow: hidden;
}
.tiddler-content th {
background-color: var(--bg-secondary);
padding: 12px 16px;
background: linear-gradient(135deg, #1971c2, #228be6);
color: white;
font-weight: 600;
text-align: left;
border: none;
border-bottom: 2px solid #1864ab;
}
.tiddler-content tr:nth-child(even) {
background-color: var(--bg-secondary);
.tiddler-content td {
padding: 10px 16px;
border: 1px solid #e9ecef;
text-align: left;
}
.tiddler-content tbody tr:nth-child(odd) {
background-color: #f8f9fa;
}
.tiddler-content tbody tr:nth-child(even) {
background-color: #ffffff;
}
.tiddler-content tbody tr:hover {
background-color: #e7f5ff;
}
/* Screenshots */