refactor: update IPC channel constants and improve markdown plugin usage

- Replaced local IPC channel constants in `index.ts` with imports from `@preload/constants/ipcChannels` for better consistency.
- Simplified the `leadRelayCapture` assignment in `TeamProvisioningService`.
- Updated markdown plugin imports across multiple components to use the new `REHYPE_PLUGINS` constant.
- Enhanced task status display logic in `TaskRow` for improved clarity.
- Adjusted CSS for better syntax highlighting in the editor.
This commit is contained in:
iliya 2026-02-23 20:02:58 +02:00 committed by Илия
parent 361828f21a
commit c3e4521cc8
14 changed files with 36 additions and 29 deletions

View file

@ -9,6 +9,13 @@
* - Manage application lifecycle
*/
import {
CONTEXT_CHANGED,
SSH_STATUS,
TEAM_CHANGE,
WINDOW_FULLSCREEN_CHANGED,
// eslint-disable-next-line boundaries/element-types -- IPC channel constants shared between main and preload
} from '@preload/constants/ipcChannels';
import {
DEFAULT_WINDOW_HEIGHT,
DEFAULT_WINDOW_WIDTH,
@ -21,11 +28,6 @@ import { app, BrowserWindow } from 'electron';
import { existsSync } from 'fs';
import { join } from 'path';
const CONTEXT_CHANGED = 'context:changed';
const SSH_STATUS = 'ssh:status';
const TEAM_CHANGE = 'team:change';
const WINDOW_FULLSCREEN_CHANGED = 'window:fullscreen-changed';
import { initializeIpcHandlers, removeIpcHandlers } from './ipc/handlers';
import { HttpServer } from './services/infrastructure/HttpServer';
import { getProjectsBasePath, getTodosBasePath } from './utils/pathDecoder';

View file

@ -1272,9 +1272,7 @@ export class TeamProvisioningService {
reject(new Error(error));
},
};
run.leadRelayCapture = {
...capture,
};
run.leadRelayCapture = capture;
});
try {

View file

@ -10,7 +10,7 @@ import {
TOOL_CALL_BORDER,
TOOL_CALL_TEXT,
} from '@renderer/constants/cssVariables';
import { rehypePlugins } from '@renderer/utils/markdownPlugins';
import { REHYPE_PLUGINS } from '@renderer/utils/markdownPlugins';
import { formatTokensCompact as formatTokens } from '@shared/utils/tokenFormatting';
import { format } from 'date-fns';
import { ChevronRight, Layers } from 'lucide-react';
@ -149,7 +149,7 @@ export const CompactBoundary = ({
{compactContent ? (
<ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={rehypePlugins}
rehypePlugins={REHYPE_PLUGINS}
components={markdownComponents}
>
{compactContent}

View file

@ -2,7 +2,7 @@ import React from 'react';
import ReactMarkdown from 'react-markdown';
import { useStore } from '@renderer/store';
import { rehypePlugins } from '@renderer/utils/markdownPlugins';
import { REHYPE_PLUGINS } from '@renderer/utils/markdownPlugins';
import { AlertTriangle, CheckCircle, FileCheck, XCircle } from 'lucide-react';
import remarkGfm from 'remark-gfm';
import { useShallow } from 'zustand/react/shallow';
@ -91,7 +91,7 @@ export const LastOutputDisplay = ({
<div className="max-h-96 overflow-y-auto px-4 py-3" data-search-content>
<ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={rehypePlugins}
rehypePlugins={REHYPE_PLUGINS}
components={mdComponents}
>
{textContent}
@ -238,7 +238,7 @@ export const LastOutputDisplay = ({
<div className="max-h-96 overflow-y-auto px-4 py-3">
<ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={rehypePlugins}
rehypePlugins={REHYPE_PLUGINS}
components={mdComponents}
>
{planContent}

View file

@ -4,7 +4,7 @@ import ReactMarkdown, { type Components } from 'react-markdown';
import { api } from '@renderer/api';
import { useTabUI } from '@renderer/hooks/useTabUI';
import { useStore } from '@renderer/store';
import { rehypePlugins } from '@renderer/utils/markdownPlugins';
import { REHYPE_PLUGINS } from '@renderer/utils/markdownPlugins';
import { createLogger } from '@shared/utils/logger';
import { format } from 'date-fns';
import { User } from 'lucide-react';
@ -448,7 +448,7 @@ const UserChatGroupInner = ({ userGroup }: Readonly<UserChatGroupProps>): React.
<div className="text-sm" style={{ color: 'var(--chat-user-text)' }} data-search-content>
<ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={rehypePlugins}
rehypePlugins={REHYPE_PLUGINS}
components={userMarkdownComponents}
>
{displayText}

View file

@ -23,7 +23,7 @@ import {
PROSE_TABLE_HEADER_BG,
} from '@renderer/constants/cssVariables';
import { useStore } from '@renderer/store';
import { rehypePlugins } from '@renderer/utils/markdownPlugins';
import { REHYPE_PLUGINS } from '@renderer/utils/markdownPlugins';
import { FileText } from 'lucide-react';
import remarkGfm from 'remark-gfm';
import { useShallow } from 'zustand/react/shallow';
@ -157,7 +157,7 @@ function createViewerMarkdownComponents(searchCtx: SearchContext | null): Compon
if (isBlock) {
return (
<code
className={`break-all font-mono text-xs ${codeClassName ?? ''}`.trim()}
className={`font-mono text-xs ${codeClassName ?? ''}`.trim()}
style={{ color: COLOR_TEXT }}
>
{hl(children)}
@ -336,7 +336,7 @@ export const MarkdownViewer: React.FC<MarkdownViewerProps> = ({
<div className="min-w-0 break-words p-4">
<ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={rehypePlugins}
rehypePlugins={REHYPE_PLUGINS}
components={components}
>
{content}

View file

@ -10,7 +10,7 @@ import ReactMarkdown from 'react-markdown';
import { markdownComponents } from '@renderer/components/chat/markdownComponents';
import { useStore } from '@renderer/store';
import { rehypePlugins } from '@renderer/utils/markdownPlugins';
import { REHYPE_PLUGINS } from '@renderer/utils/markdownPlugins';
import { X } from 'lucide-react';
import remarkGfm from 'remark-gfm';
@ -153,7 +153,7 @@ export const UpdateDialog = (): React.JSX.Element | null => {
>
<ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={rehypePlugins}
rehypePlugins={REHYPE_PLUGINS}
components={markdownComponents}
>
{normalizeReleaseNotes(releaseNotes)}

View file

@ -32,9 +32,9 @@ export const SidebarTaskItem = ({ task }: SidebarTaskItemProps): React.JSX.Eleme
const unreadCount = useUnreadCommentCount(task.teamName, task.id, task.comments);
const cfg =
task.kanbanColumn === 'approved'
? ({ icon: ShieldCheck, color: 'text-emerald-400', label: 'approved' } as const)
? ({ icon: ShieldCheck, color: 'text-teal-400', label: 'approved' } as const)
: task.kanbanColumn === 'review'
? ({ icon: Eye, color: 'text-amber-400', label: 'in review' } as const)
? ({ icon: Eye, color: 'text-orange-400', label: 'in review' } as const)
: (statusConfig[task.status] ?? statusConfig.pending);
const StatusIcon = cfg.icon;
const dateLabel = formatTaskDate(task.createdAt);

View file

@ -29,7 +29,7 @@ export function taskMatchesStatus(
statusIds: Set<TaskStatusFilterId>
): boolean {
if (statusIds.size === 0) return false;
if (statusIds.size === STATUS_OPTIONS.length) return true;
if (statusIds.size === STATUS_OPTIONS.length) return task.status !== 'deleted';
const inTodo = task.status === 'pending' && !task.kanbanColumn;
const inProgress = task.status === 'in_progress' && !task.kanbanColumn;

View file

@ -100,8 +100,9 @@ export const MemberCard = ({
}}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ' || e.key === 'Spacebar') {
e.stopPropagation();
e.preventDefault();
e.stopPropagation();
onOpenTask?.();
}
}}
>

View file

@ -1,3 +1,5 @@
import { KANBAN_COLUMN_DISPLAY, TASK_STATUS_LABELS } from '@renderer/utils/memberHelpers';
import type { TeamTaskWithKanban } from '@shared/types';
interface TaskRowProps {
@ -14,7 +16,9 @@ export const TaskRow = ({ task }: TaskRowProps): React.JSX.Element => {
<td className="px-3 py-2 text-sm text-[var(--color-text)]">{task.subject}</td>
<td className="px-3 py-2 text-xs text-[var(--color-text-muted)]">{task.owner ?? '\u2014'}</td>
<td className="px-3 py-2 text-xs text-[var(--color-text-muted)]">
{task.kanbanColumn ?? task.status}
{task.kanbanColumn && task.kanbanColumn in KANBAN_COLUMN_DISPLAY
? KANBAN_COLUMN_DISPLAY[task.kanbanColumn].label
: (TASK_STATUS_LABELS[task.status] ?? task.status)}
</td>
<td className="px-3 py-2 text-xs">
{blockedByIds.length > 0 ? (

View file

@ -389,10 +389,12 @@
background: transparent;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-addition {
.hljs-selector-tag {
color: var(--syntax-keyword);
}
.hljs-addition {
color: var(--diff-added-text);
}
.hljs-string,
.hljs-doctag {
color: var(--syntax-string);

View file

@ -5,4 +5,4 @@
import rehypeHighlight from 'rehype-highlight';
export const rehypePlugins = [rehypeHighlight];
export const REHYPE_PLUGINS = [rehypeHighlight];

View file

@ -77,7 +77,7 @@ export function groupTasksByProject(tasks: GlobalTask[]): ProjectTaskGroup[] {
for (const task of tasks) {
const path = task.projectPath?.trim() ?? '';
const key = path ? normalizePath(path) : NO_PROJECT_KEY;
const key = path ? normalizePath(trimTrailingPathSep(path)) : NO_PROJECT_KEY;
let entry = byKey.get(key);
if (!entry) {
entry = { path: path || '', tasks: [] };