chore: clean up project configuration and remove unused dependencies

- Updated knip.json to exclude unused Remotion paths and dependencies.
- Cleaned up pnpm-lock.yaml by removing obsolete Remotion packages.
- Refactored TypeScript function signatures in main files for improved clarity.
- Enhanced various components for better code readability and maintainability.
This commit is contained in:
matt 2026-02-16 23:27:43 +09:00
parent aacadf1a2d
commit da1a8998fc
11 changed files with 46 additions and 1425 deletions

View file

@ -6,11 +6,9 @@
"src/preload/index.ts", "src/preload/index.ts",
"src/renderer/main.tsx", "src/renderer/main.tsx",
"electron.vite.config.ts", "electron.vite.config.ts",
"vite.standalone.config.ts", "vite.standalone.config.ts"
"remotion/index.ts",
"remotion/**/*.{ts,tsx}"
], ],
"project": ["src/**/*.{ts,tsx}!", "remotion/**/*.{ts,tsx}!"], "project": ["src/**/*.{ts,tsx}!"],
"ignore": ["tsconfig*.json"], "ignore": ["tsconfig*.json"],
"paths": { "paths": {
"@main/*": ["./src/main/*"], "@main/*": ["./src/main/*"],
@ -18,6 +16,5 @@
"@preload/*": ["./src/preload/*"], "@preload/*": ["./src/preload/*"],
"@shared/*": ["./src/shared/*"] "@shared/*": ["./src/shared/*"]
}, },
"ignoreDependencies": ["@remotion/light-leaks", "remotion"],
"ignoreBinaries": ["pkg"] "ignoreBinaries": ["pkg"]
} }

File diff suppressed because it is too large Load diff

View file

@ -116,7 +116,7 @@ function wireFileWatcherEvents(context: ServiceContext): void {
} }
// Wire file-change events to renderer and HTTP SSE // Wire file-change events to renderer and HTTP SSE
const fileChangeHandler = (event: unknown) => { const fileChangeHandler = (event: unknown): void => {
if (mainWindow && !mainWindow.isDestroyed()) { if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.webContents.send('file-change', event); mainWindow.webContents.send('file-change', event);
} }
@ -126,7 +126,7 @@ function wireFileWatcherEvents(context: ServiceContext): void {
fileChangeCleanup = () => context.fileWatcher.off('file-change', fileChangeHandler); fileChangeCleanup = () => context.fileWatcher.off('file-change', fileChangeHandler);
// Forward checklist-change events to renderer and HTTP SSE (mirrors file-change pattern above) // Forward checklist-change events to renderer and HTTP SSE (mirrors file-change pattern above)
const todoChangeHandler = (event: unknown) => { const todoChangeHandler = (event: unknown): void => {
if (mainWindow && !mainWindow.isDestroyed()) { if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.webContents.send('todo-change', event); mainWindow.webContents.send('todo-change', event);
} }

View file

@ -73,6 +73,7 @@ export class HttpServer {
await this.app.register(cors, { origin: origins, credentials: true }); await this.app.register(cors, { origin: origins, credentials: true });
} else { } else {
// Default: allow all localhost origins // Default: allow all localhost origins
// eslint-disable-next-line security/detect-unsafe-regex -- anchored, no backtracking risk
const localhostPattern = /^https?:\/\/(?:localhost|127\.0\.0\.1)(?::\d+)?$/; const localhostPattern = /^https?:\/\/(?:localhost|127\.0\.0\.1)(?::\d+)?$/;
await this.app.register(cors, { await this.app.register(cors, {
origin: (origin, cb) => { origin: (origin, cb) => {

View file

@ -20,11 +20,7 @@ import {
getTodosBasePath, getTodosBasePath,
setClaudeBasePathOverride, setClaudeBasePathOverride,
} from './utils/pathDecoder'; } from './utils/pathDecoder';
import { import { LocalFileSystemProvider, NotificationManager, ServiceContext } from './services';
LocalFileSystemProvider,
NotificationManager,
ServiceContext,
} from './services';
import type { HttpServices } from './http'; import type { HttpServices } from './http';
import type { SshConnectionManager } from './services/infrastructure/SshConnectionManager'; import type { SshConnectionManager } from './services/infrastructure/SshConnectionManager';
@ -59,7 +55,12 @@ const updaterServiceStub = {
/** No-op SshConnectionManager stub — SSH is managed per-user in the Electron app. */ /** No-op SshConnectionManager stub — SSH is managed per-user in the Electron app. */
const sshConnectionManagerStub = { const sshConnectionManagerStub = {
getStatus: () => ({ state: 'disconnected' as const, host: null, error: null, remoteProjectsPath: null }), getStatus: () => ({
state: 'disconnected' as const,
host: null,
error: null,
remoteProjectsPath: null,
}),
getProvider: () => new LocalFileSystemProvider(), getProvider: () => new LocalFileSystemProvider(),
isRemote: () => false, isRemote: () => false,
connect: async () => {}, connect: async () => {},
@ -148,7 +149,7 @@ async function start(): Promise<void> {
}; };
// No-op mode switch handler (no SSH in standalone) // No-op mode switch handler (no SSH in standalone)
const modeSwitchHandler = async () => {}; const modeSwitchHandler = async (): Promise<void> => {};
// Start the server // Start the server
const port = await httpServer.start(services, modeSwitchHandler, PORT, HOST); const port = await httpServer.start(services, modeSwitchHandler, PORT, HOST);

View file

@ -272,7 +272,7 @@ export const RankedInjectionList = ({
</button> </button>
{/* Copy path button for CLAUDE.md and File items */} {/* Copy path button for CLAUDE.md and File items */}
{copyPath && ( {copyPath && (
<span className="shrink-0" onClick={(e) => e.stopPropagation()}> <span className="shrink-0">
<CopyButton text={copyPath} inline /> <CopyButton text={copyPath} inline />
</span> </span>
)} )}

View file

@ -37,6 +37,7 @@ let globalResolver: ConfirmResolver = null;
* Usage: * Usage:
* const confirmed = await confirm({ title: 'Delete?', message: 'This cannot be undone.' }); * const confirmed = await confirm({ title: 'Delete?', message: 'This cannot be undone.' });
*/ */
// eslint-disable-next-line react-refresh/only-export-components -- imperative API shares singleton state with component
export async function confirm(opts: { export async function confirm(opts: {
title: string; title: string;
message: string; message: string;

View file

@ -33,14 +33,20 @@ export const UpdateBanner = (): React.JSX.Element | null => {
> >
{isDownloading ? ( {isDownloading ? (
<div className="pr-8"> <div className="pr-8">
<div className="mb-1.5 flex items-center gap-2 text-xs" style={{ color: 'var(--color-text-secondary)' }}> <div
className="mb-1.5 flex items-center gap-2 text-xs"
style={{ color: 'var(--color-text-secondary)' }}
>
<Loader2 className="size-3.5 shrink-0 animate-spin text-blue-400" /> <Loader2 className="size-3.5 shrink-0 animate-spin text-blue-400" />
<span>Updating app</span> <span>Updating app</span>
<span className="tabular-nums" style={{ color: 'var(--color-text-muted)' }}> <span className="tabular-nums" style={{ color: 'var(--color-text-muted)' }}>
{clampedPercent}% {clampedPercent}%
</span> </span>
</div> </div>
<div className="h-1 w-full overflow-hidden rounded-full" style={{ backgroundColor: 'var(--color-border)' }}> <div
className="h-1 w-full overflow-hidden rounded-full"
style={{ backgroundColor: 'var(--color-border)' }}
>
<div <div
className="h-full rounded-full bg-blue-500 transition-all duration-300 ease-out" className="h-full rounded-full bg-blue-500 transition-all duration-300 ease-out"
style={{ width: `${clampedPercent}%` }} style={{ width: `${clampedPercent}%` }}
@ -74,7 +80,7 @@ export const UpdateBanner = (): React.JSX.Element | null => {
{/* Dismiss */} {/* Dismiss */}
<button <button
onClick={dismissUpdateBanner} onClick={dismissUpdateBanner}
className="absolute right-3 top-1/2 -translate-y-1/2 shrink-0 rounded p-0.5 transition-colors hover:bg-white/10" className="absolute right-3 top-1/2 shrink-0 -translate-y-1/2 rounded p-0.5 transition-colors hover:bg-white/10"
style={{ color: 'var(--color-text-muted)' }} style={{ color: 'var(--color-text-muted)' }}
> >
<X className="size-3.5" /> <X className="size-3.5" />

View file

@ -333,9 +333,7 @@ export const SidebarHeader = (): React.JSX.Element => {
style={ style={
{ {
height: `${HEADER_ROW1_HEIGHT}px`, height: `${HEADER_ROW1_HEIGHT}px`,
paddingLeft: isMacElectron paddingLeft: isMacElectron ? 'var(--macos-traffic-light-padding-left, 72px)' : '16px',
? 'var(--macos-traffic-light-padding-left, 72px)'
: '16px',
WebkitAppRegion: isMacElectron ? 'drag' : undefined, WebkitAppRegion: isMacElectron ? 'drag' : undefined,
} as React.CSSProperties } as React.CSSProperties
} }

View file

@ -61,21 +61,14 @@ const ConsumptionBadge = ({
contextConsumption: number; contextConsumption: number;
phaseBreakdown?: PhaseTokenBreakdown[]; phaseBreakdown?: PhaseTokenBreakdown[];
}>): React.JSX.Element => { }>): React.JSX.Element => {
const [showPopover, setShowPopover] = useState(false); const [popoverPosition, setPopoverPosition] = useState<{
top: number;
left: number;
} | null>(null);
const badgeRef = useRef<HTMLSpanElement>(null); const badgeRef = useRef<HTMLSpanElement>(null);
const isHigh = contextConsumption > 150_000; const isHigh = contextConsumption > 150_000;
// Calculate popover position relative to viewport for portal rendering const showPopover = popoverPosition !== null;
const popoverPosition =
showPopover && badgeRef.current
? (() => {
const rect = badgeRef.current.getBoundingClientRect();
return {
top: rect.top - 6,
left: rect.left + rect.width / 2,
};
})()
: null;
return ( return (
// eslint-disable-next-line jsx-a11y/no-static-element-interactions -- tooltip trigger via hover, not interactive // eslint-disable-next-line jsx-a11y/no-static-element-interactions -- tooltip trigger via hover, not interactive
@ -83,8 +76,16 @@ const ConsumptionBadge = ({
ref={badgeRef} ref={badgeRef}
className="tabular-nums" className="tabular-nums"
style={{ color: isHigh ? 'rgb(251, 191, 36)' : undefined }} style={{ color: isHigh ? 'rgb(251, 191, 36)' : undefined }}
onMouseEnter={() => setShowPopover(true)} onMouseEnter={() => {
onMouseLeave={() => setShowPopover(false)} const rect = badgeRef.current?.getBoundingClientRect();
if (rect) {
setPopoverPosition({
top: rect.top - 6,
left: rect.left + rect.width / 2,
});
}
}}
onMouseLeave={() => setPopoverPosition(null)}
> >
{formatTokensCompact(contextConsumption)} {formatTokensCompact(contextConsumption)}
{showPopover && {showPopover &&

View file

@ -221,7 +221,8 @@ export function initializeNotificationListeners(): () => void {
(eventProjectBaseId == null || selectedProjectBaseId === eventProjectBaseId); (eventProjectBaseId == null || selectedProjectBaseId === eventProjectBaseId);
const isTopLevelSessionEvent = !event.isSubagent; const isTopLevelSessionEvent = !event.isSubagent;
const isUnknownSessionInSidebar = const isUnknownSessionInSidebar =
event.sessionId == null || !state.sessions.some((session) => session.id === event.sessionId); event.sessionId == null ||
!state.sessions.some((session) => session.id === event.sessionId);
const shouldRefreshForPotentialNewSession = const shouldRefreshForPotentialNewSession =
isTopLevelSessionEvent && isTopLevelSessionEvent &&
matchesSelectedProject && matchesSelectedProject &&