fix(build): resolve TypeScript errors and add missing dependencies

- Add missing zustand dependency to package.json
- Fix unused variable errors in ToolWidgets.tsx
- Remove invalid 'white' theme comparison in claudeSyntaxTheme.ts
- Add proper TypeScript types to stores using StateCreator pattern
- Add null checks and type casting in Settings.tsx filter operations
- Add onChange handler to Switch component to suppress React warning
- Add 'check' script for TypeScript validation

These changes ensure the TypeScript build passes without errors.
This commit is contained in:
Mufeed VH
2025-07-28 15:28:07 +05:30
parent c87d36e118
commit efdeff7a31
8 changed files with 53 additions and 35 deletions

View File

@@ -44,6 +44,7 @@
"tailwind-merge": "^2.6.0",
"tailwindcss": "^4.1.8",
"zod": "^3.24.1",
"zustand": "^5.0.6",
},
"devDependencies": {
"@tauri-apps/cli": "^2",
@@ -1021,6 +1022,8 @@
"zod": ["zod@3.25.67", "", {}, "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw=="],
"zustand": ["zustand@5.0.6", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-ihAqNeUVhe0MAD+X8M5UzqyZ9k3FFZLBTtqo6JLPwV53cbRB/mJwBI0PxcIgqhBBHlEs8G45OTDTMq3gNcLq3A=="],
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
"@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],

View File

@@ -8,7 +8,8 @@
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"tauri": "tauri"
"tauri": "tauri",
"check": "tsc --noEmit && cd src-tauri && cargo check"
},
"dependencies": {
"@hookform/resolvers": "^3.9.1",

View File

@@ -170,12 +170,12 @@ export const Settings: React.FC<SettingsProps> = ({
const updatedSettings: ClaudeSettings = {
...settings,
permissions: {
allow: allowRules.map(rule => rule.value).filter(v => v.trim()),
deny: denyRules.map(rule => rule.value).filter(v => v.trim()),
allow: allowRules.map(rule => rule.value).filter(v => v && String(v).trim()),
deny: denyRules.map(rule => rule.value).filter(v => v && String(v).trim()),
},
env: envVars.reduce((acc, { key, value }) => {
if (key.trim() && value.trim()) {
acc[key] = value;
if (key && String(key).trim() && value && String(value).trim()) {
acc[key] = String(value);
}
return acc;
}, {} as Record<string, string>),

View File

@@ -632,9 +632,6 @@ export const BashWidget: React.FC<{
description?: string;
result?: any;
}> = ({ command, description, result }) => {
const { theme } = useTheme();
const syntaxTheme = getClaudeSyntaxTheme(theme);
// Extract result content if available
let resultContent = '';
let isError = false;

View File

@@ -52,6 +52,7 @@ const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
checked={checked}
disabled={disabled}
className="sr-only"
onChange={() => {}}
{...props}
/>
</button>

View File

@@ -124,7 +124,7 @@ export const getClaudeSyntaxTheme = (theme: ThemeMode): any => {
overflow: 'auto',
},
':not(pre) > code[class*="language-"]': {
background: theme === 'light' || theme === 'white'
background: theme === 'light'
? 'rgba(139, 92, 246, 0.1)'
: 'rgba(139, 92, 246, 0.1)',
padding: '0.1em 0.3em',

View File

@@ -1,5 +1,6 @@
import { create } from 'zustand';
import { subscribeWithSelector } from 'zustand/middleware';
import type { StateCreator } from 'zustand';
import { api } from '@/lib/api';
import type { AgentRunWithMetrics } from '@/lib/api';
@@ -32,8 +33,12 @@ interface AgentState {
pollingInterval: NodeJS.Timeout | null;
}
export const useAgentStore = create<AgentState>()(
subscribeWithSelector((set, get) => ({
const agentStore: StateCreator<
AgentState,
[],
[['zustand/subscribeWithSelector', never]],
AgentState
> = (set, get) => ({
// Initial state
agentRuns: [],
runningAgents: new Set(),
@@ -59,8 +64,8 @@ export const useAgentStore = create<AgentState>()(
try {
const runs = await api.listAgentRuns();
const runningIds = runs
.filter(r => r.status === 'running' || r.status === 'pending')
.map(r => r.id?.toString() || '')
.filter((r) => r.status === 'running' || r.status === 'pending')
.map((r) => r.id?.toString() || '')
.filter(Boolean);
set({
@@ -83,7 +88,7 @@ export const useAgentStore = create<AgentState>()(
try {
const output = await api.getAgentRunWithRealTimeMetrics(runId).then(run => run.output || '');
set(state => ({
set((state) => ({
sessionOutputs: {
...state.sessionOutputs,
[runId]: output
@@ -107,7 +112,7 @@ export const useAgentStore = create<AgentState>()(
const run = await api.getAgentRun(runId);
// Update local state immediately
set(state => ({
set((state) => ({
agentRuns: [run, ...state.agentRuns],
runningAgents: new Set([...state.runningAgents, runId.toString()])
}));
@@ -127,8 +132,8 @@ export const useAgentStore = create<AgentState>()(
await api.killAgentSession(runId);
// Update local state
set(state => ({
agentRuns: state.agentRuns.map(r =>
set((state) => ({
agentRuns: state.agentRuns.map((r) =>
r.id === runId ? { ...r, status: 'cancelled' } : r
),
runningAgents: new Set(
@@ -147,7 +152,7 @@ export const useAgentStore = create<AgentState>()(
deleteAgentRun: async (runId: number) => {
try {
// First ensure the run is cancelled if it's still running
const run = get().agentRuns.find(r => r.id === runId);
const run = get().agentRuns.find((r) => r.id === runId);
if (run && (run.status === 'running' || run.status === 'pending')) {
await api.killAgentSession(runId);
}
@@ -156,8 +161,8 @@ export const useAgentStore = create<AgentState>()(
// The run will remain in the database but won't be shown in the UI
// Update local state
set(state => ({
agentRuns: state.agentRuns.filter(r => r.id !== runId),
set((state) => ({
agentRuns: state.agentRuns.filter((r) => r.id !== runId),
runningAgents: new Set(
[...state.runningAgents].filter(id => id !== runId.toString())
),
@@ -178,8 +183,8 @@ export const useAgentStore = create<AgentState>()(
// Handle real-time agent run updates
handleAgentRunUpdate: (run: AgentRunWithMetrics) => {
set(state => {
const existingIndex = state.agentRuns.findIndex(r => r.id === run.id);
set((state) => {
const existingIndex = state.agentRuns.findIndex((r) => r.id === run.id);
const updatedRuns = [...state.agentRuns];
if (existingIndex >= 0) {
@@ -189,8 +194,8 @@ export const useAgentStore = create<AgentState>()(
}
const runningIds = updatedRuns
.filter(r => r.status === 'running' || r.status === 'pending')
.map(r => r.id?.toString() || '')
.filter((r) => r.status === 'running' || r.status === 'pending')
.map((r) => r.id?.toString() || '')
.filter(Boolean);
return {
@@ -228,5 +233,8 @@ export const useAgentStore = create<AgentState>()(
set({ pollingInterval: null });
}
}
}))
});
export const useAgentStore = create<AgentState>()(
subscribeWithSelector(agentStore)
);

View File

@@ -1,5 +1,6 @@
import { create } from 'zustand';
import { subscribeWithSelector } from 'zustand/middleware';
import type { StateCreator } from 'zustand';
import { api } from '@/lib/api';
import type { Session, Project } from '@/lib/api';
@@ -30,8 +31,12 @@ interface SessionState {
handleOutputUpdate: (sessionId: string, output: string) => void;
}
export const useSessionStore = create<SessionState>()(
subscribeWithSelector((set, get) => ({
const sessionStore: StateCreator<
SessionState,
[],
[['zustand/subscribeWithSelector', never]],
SessionState
> = (set, get) => ({
// Initial state
projects: [],
sessions: {},
@@ -62,7 +67,7 @@ export const useSessionStore = create<SessionState>()(
set({ isLoadingSessions: true, error: null });
try {
const projectSessions = await api.getProjectSessions(projectId);
set(state => ({
set((state) => ({
sessions: {
...state.sessions,
[projectId]: projectSessions
@@ -85,7 +90,7 @@ export const useSessionStore = create<SessionState>()(
if (sessionId) {
// Find session across all projects
for (const projectSessions of Object.values(sessions)) {
const found = projectSessions.find(s => s.id === sessionId);
const found = projectSessions.find((s) => s.id === sessionId);
if (found) {
currentSession = found;
break;
@@ -101,7 +106,7 @@ export const useSessionStore = create<SessionState>()(
set({ isLoadingOutputs: true, error: null });
try {
const output = await api.getClaudeSessionOutput(sessionId);
set(state => ({
set((state) => ({
sessionOutputs: {
...state.sessionOutputs,
[sessionId]: output
@@ -123,10 +128,10 @@ export const useSessionStore = create<SessionState>()(
console.warn('deleteSession not implemented in API');
// Update local state
set(state => ({
set((state) => ({
sessions: {
...state.sessions,
[projectId]: state.sessions[projectId]?.filter(s => s.id !== sessionId) || []
[projectId]: state.sessions[projectId]?.filter((s) => s.id !== sessionId) || []
},
currentSessionId: state.currentSessionId === sessionId ? null : state.currentSessionId,
currentSession: state.currentSession?.id === sessionId ? null : state.currentSession,
@@ -150,7 +155,7 @@ export const useSessionStore = create<SessionState>()(
set(state => {
const projectId = session.project_id;
const projectSessions = state.sessions[projectId] || [];
const existingIndex = projectSessions.findIndex(s => s.id === session.id);
const existingIndex = projectSessions.findIndex((s) => s.id === session.id);
let updatedSessions;
if (existingIndex >= 0) {
@@ -172,12 +177,15 @@ export const useSessionStore = create<SessionState>()(
// Handle output update
handleOutputUpdate: (sessionId: string, output: string) => {
set(state => ({
set((state) => ({
sessionOutputs: {
...state.sessionOutputs,
[sessionId]: output
}
}));
}
}))
});
export const useSessionStore = create<SessionState>()(
subscribeWithSelector(sessionStore)
);