fix(ci): resolve validate job failures - add ESLint cache, fix 6 lint errors
Made-with: Cursor
This commit is contained in:
parent
caa2cae575
commit
b162cb1854
8 changed files with 29 additions and 14 deletions
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
|
|
@ -46,6 +46,14 @@ jobs:
|
|||
- name: Install dependencies
|
||||
run: pnpm install --no-frozen-lockfile
|
||||
|
||||
- name: Restore ESLint cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .eslintcache
|
||||
key: eslint-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'eslint.config.*') }}
|
||||
restore-keys: |
|
||||
eslint-${{ runner.os }}-
|
||||
|
||||
- name: Typecheck
|
||||
run: pnpm typecheck
|
||||
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -46,6 +46,7 @@ temp/
|
|||
|
||||
|
||||
eslint-fix/
|
||||
.eslintcache
|
||||
remotion/*
|
||||
|
||||
.home/
|
||||
|
|
@ -30,8 +30,8 @@
|
|||
"dist:linux": "electron-builder --linux",
|
||||
"preview": "electron-vite preview",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "eslint src/",
|
||||
"lint:fix": "eslint src/ --fix",
|
||||
"lint": "eslint src/ --cache --cache-location .eslintcache --cache-strategy content",
|
||||
"lint:fix": "eslint src/ --fix --cache --cache-location .eslintcache --cache-strategy content",
|
||||
"format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css}\"",
|
||||
"format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,css}\"",
|
||||
"check": "pnpm typecheck && pnpm lint && pnpm test && pnpm build",
|
||||
|
|
|
|||
|
|
@ -928,13 +928,9 @@ export class TeamDataService {
|
|||
await this.taskWriter.setNeedsClarification(teamName, taskId, null);
|
||||
}
|
||||
|
||||
if (task?.owner) {
|
||||
if (task?.owner && !this.isLeadOwner(task.owner, leadName)) {
|
||||
// UX: don't echo a user comment as an inbox notification "from the lead" when the
|
||||
// task is already owned by the lead. This creates confusing self-notifications.
|
||||
if (this.isLeadOwner(task.owner, leadName)) {
|
||||
return comment;
|
||||
}
|
||||
|
||||
const parts = [
|
||||
`Comment on task #${taskId} "${task.subject}":\n\n${text}`,
|
||||
`\n${AGENT_BLOCK_OPEN}`,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
import { Button } from '@renderer/components/ui/button';
|
||||
import { useStore } from '@renderer/store';
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ export const MemberLogsTab = ({
|
|||
cancelled = true;
|
||||
if (interval) clearInterval(interval);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- intervalsKey drives refresh; deps intentionally minimal to avoid refetch loops
|
||||
}, [teamName, memberName, taskId, taskOwner, taskStatus, intervalsKey]);
|
||||
|
||||
const handleExpand = useCallback(
|
||||
|
|
|
|||
|
|
@ -185,6 +185,16 @@ export const ChangeReviewDialog = ({
|
|||
[scrollToFile]
|
||||
);
|
||||
|
||||
// Double rAF to ensure DOM/layout is ready before scrolling (reduces nesting in keydown handler)
|
||||
const scheduleScrollToFile = useCallback(
|
||||
(path: string) => {
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => scrollToFile(path));
|
||||
});
|
||||
},
|
||||
[scrollToFile]
|
||||
);
|
||||
|
||||
// Accept/Reject all across all files
|
||||
const handleAcceptAll = useCallback(() => {
|
||||
if (!activeChangeSet) return;
|
||||
|
|
@ -629,9 +639,7 @@ export const ChangeReviewDialog = ({
|
|||
};
|
||||
addReviewFile(snap.file, { index: snap.index, content: restoredContent });
|
||||
setActiveFilePath(snap.file.filePath);
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => scrollToFile(snap.file.filePath));
|
||||
});
|
||||
scheduleScrollToFile(snap.file.filePath);
|
||||
updateEditedContent(snap.file.filePath, snap.restoreContent);
|
||||
// Ensure editedContents is set before saveEditedFile reads it.
|
||||
void Promise.resolve().then(() => saveEditedFile(snap.file.filePath, projectPath));
|
||||
|
|
@ -687,7 +695,7 @@ export const ChangeReviewDialog = ({
|
|||
updateEditedContent,
|
||||
saveEditedFile,
|
||||
projectPath,
|
||||
scrollToFile,
|
||||
scheduleScrollToFile,
|
||||
]);
|
||||
|
||||
// Cmd+N IPC listener (forwarded from main process)
|
||||
|
|
|
|||
|
|
@ -52,7 +52,9 @@ export function useChipDraftPersistence(key: string): UseChipDraftResult {
|
|||
// without stale closures, using the same sync-ref pattern as keyRef.
|
||||
const chipsRef = useRef<InlineChip[]>([]);
|
||||
|
||||
keyRef.current = key;
|
||||
useEffect(() => {
|
||||
keyRef.current = key;
|
||||
}, [key]);
|
||||
|
||||
// Load on mount
|
||||
useEffect(() => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue