Skip to content

Commit 4b9510d

Browse files
0xSerowtfsayo
andauthored
chore(lint-BIOME): Improving errors and warnings (#2990)
* clean up 15 errors and 60 warnings * smoke * smokeTest pass remove track * set up lockfile --------- Co-authored-by: Sero <69639595+Seroxdesign@users.noreply.github.com> Co-authored-by: Sayo <hi@sayo.wtf>
1 parent 37c812c commit 4b9510d

33 files changed

+837
-813
lines changed

agent/src/__tests__/client-type-identification.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { describe, it, expect } from "@jest/globals";
44
// Helper function to identify client types
55
function determineClientType(client: Client): string {
66
// Check if client has a direct type identifier
7-
if ("type" in client) {
8-
return (client as any).type;
7+
if ("type" in client && typeof client.type === "string") {
8+
return client.type;
99
}
1010

1111
// Check constructor name

client/src/components/app-sidebar.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export function AppSidebar() {
3737
<SidebarMenuButton size="lg" asChild>
3838
<NavLink to="/">
3939
<img
40+
alt="elizaos-icon"
4041
src="/elizaos-icon.png"
4142
width="100%"
4243
height="100%"
@@ -62,8 +63,8 @@ export function AppSidebar() {
6263
{query?.isPending ? (
6364
<div>
6465
{Array.from({ length: 5 }).map(
65-
(_, index) => (
66-
<SidebarMenuItem key={index}>
66+
(_, _index) => (
67+
<SidebarMenuItem key={"skeleton-item"}>
6768
<SidebarMenuSkeleton />
6869
</SidebarMenuItem>
6970
)

client/src/components/array-input.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export default function ArrayInput({
1313
<Label>{title}</Label>
1414
<div className="p-2 bg-card rounded-md border">
1515
<div className="space-y-2">
16-
{data?.map((b: string, idx: number) => (
17-
<Input value={b} key={idx} className="bg-background" />
16+
{data?.map((b: string, _idx: number) => (
17+
<Input value={b} key={b} className="bg-background" />
1818
))}
1919
</div>
2020
</div>

client/src/components/audio-recorder.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ export const AudioRecorder = ({
4343
const { toast } = useToast();
4444
// States
4545
const [isRecording, setIsRecording] = useState<boolean>(false);
46-
// @ts-expect-error - isRecordingFinished is unused, but would break the 2D array if removed
47-
const [isRecordingFinished, setIsRecordingFinished] =
46+
const [_, setIsRecordingFinished] =
4847
useState<boolean>(false);
4948
const [timer, setTimer] = useState<number>(0);
5049
const [currentRecord, setCurrentRecord] = useState<Record>({
@@ -96,7 +95,7 @@ export const AudioRecorder = ({
9695
});
9796

9897
function startRecording() {
99-
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
98+
if (navigator.mediaDevices?.getUserMedia) {
10099
navigator.mediaDevices
101100
.getUserMedia({
102101
audio: true,
@@ -182,7 +181,9 @@ export const AudioRecorder = ({
182181
analyser.disconnect();
183182
}
184183
if (stream) {
185-
stream.getTracks().forEach((track) => track.stop());
184+
for (const track of stream.getTracks()) {
185+
track.stop();
186+
}
186187
}
187188
if (audioContext) {
188189
audioContext.close();

client/src/components/chat.tsx

+14-13
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ChatInput } from "@/components/ui/chat/chat-input";
88
import { ChatMessageList } from "@/components/ui/chat/chat-message-list";
99
import { useTransition, animated, type AnimatedProps } from "@react-spring/web";
1010
import { Paperclip, Send, X } from "lucide-react";
11-
import { useEffect, useRef, useState } from "react";
11+
import { useEffect, useRef, useState, useCallback } from "react";
1212
import type { Content, UUID } from "@elizaos/core";
1313
import { useMutation, useQueryClient } from "@tanstack/react-query";
1414
import { apiClient } from "@/lib/api";
@@ -49,12 +49,13 @@ export default function Page({ agentId }: { agentId: UUID }) {
4949
const getMessageVariant = (role: string) =>
5050
role !== "user" ? "received" : "sent";
5151

52-
const scrollToBottom = () => {
52+
const scrollToBottom = useCallback(() => {
5353
if (messagesContainerRef.current) {
5454
messagesContainerRef.current.scrollTop =
5555
messagesContainerRef.current.scrollHeight;
5656
}
57-
};
57+
}, []);
58+
5859
useEffect(() => {
5960
scrollToBottom();
6061
}, [queryClient.getQueryData(["messages", agentId])]);
@@ -153,7 +154,7 @@ export default function Page({ agentId }: { agentId: UUID }) {
153154

154155
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
155156
const file = e.target.files?.[0];
156-
if (file && file.type.startsWith("image/")) {
157+
if (file?.type.startsWith("image/")) {
157158
setSelectedFile(file);
158159
}
159160
};
@@ -176,12 +177,12 @@ export default function Page({ agentId }: { agentId: UUID }) {
176177
<div className="flex flex-col w-full h-[calc(100dvh)] p-4">
177178
<div className="flex-1 overflow-y-auto">
178179
<ChatMessageList ref={messagesContainerRef}>
179-
{transitions((styles, message) => {
180+
{transitions((style, message: ContentWithUser) => {
180181
const variant = getMessageVariant(message?.user);
181182
return (
182183
<CustomAnimatedDiv
183184
style={{
184-
...styles,
185+
...style,
185186
display: "flex",
186187
flexDirection: "column",
187188
gap: "0.5rem",
@@ -211,22 +212,21 @@ export default function Page({ agentId }: { agentId: UUID }) {
211212
{/* Attachments */}
212213
<div>
213214
{message?.attachments?.map(
214-
(attachment, idx) => (
215+
(attachment: IAttachment) => (
215216
<div
216217
className="flex flex-col gap-1 mt-2"
217-
key={idx}
218+
key={`${attachment.url}-${attachment.title}`}
218219
>
219220
<img
220-
src={
221-
attachment.url
222-
}
221+
alt="attachment"
222+
src={attachment.url}
223223
width="100%"
224224
height="100%"
225225
className="w-64 rounded-md"
226226
/>
227227
<div className="flex items-center justify-between gap-4">
228-
<span></span>
229-
<span></span>
228+
<span />
229+
<span />
230230
</div>
231231
</div>
232232
)
@@ -298,6 +298,7 @@ export default function Page({ agentId }: { agentId: UUID }) {
298298
<X />
299299
</Button>
300300
<img
301+
alt="Selected file"
301302
src={URL.createObjectURL(selectedFile)}
302303
height="100%"
303304
width="100%"

client/src/components/copy-button.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useState } from "react";
33
import { Button } from "@/components/ui/button";
44
import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
55

6-
const CopyButton = ({ text }: { text: any }) => {
6+
const CopyButton = ({ text }: { text: string }) => {
77
const [copied, setCopied] = useState(false);
88

99
const handleCopy = () => {

client/src/components/ui/breadcrumb.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ const BreadcrumbPage = React.forwardRef<
6262
React.ComponentPropsWithoutRef<"span">
6363
>(({ className, ...props }, ref) => (
6464
<span
65+
tabIndex={0}
6566
ref={ref}
6667
role="link"
6768
aria-disabled="true"

client/src/components/ui/chat/chat-tts-button.tsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ export default function ChatTtsButton({
6262
if (audioBlob) {
6363
play();
6464
return;
65-
} else {
66-
mutation.mutate();
6765
}
6866
};
6967

@@ -72,7 +70,7 @@ export default function ChatTtsButton({
7270
return (
7371
<div>
7472
{audioBlob ? (
75-
<audio
73+
<audio crossOrigin="anonymous" playsInline
7674
ref={audioRef}
7775
onEnded={() => {
7876
setPlaying(false);

client/src/components/ui/chat/hooks/useAutoScroll.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ interface UseAutoScrollOptions {
1313
}
1414

1515
export function useAutoScroll(options: UseAutoScrollOptions = {}) {
16-
const { offset = 20, smooth = false, content } = options;
16+
const { offset = 20, smooth = false } = options;
1717
const scrollRef = useRef<HTMLDivElement>(null);
1818
const lastContentHeight = useRef(0);
1919
const userHasScrolled = useRef(false);
@@ -94,7 +94,7 @@ export function useAutoScroll(options: UseAutoScrollOptions = {}) {
9494
}
9595
lastContentHeight.current = currentHeight;
9696
}
97-
}, [content, scrollState.autoScrollEnabled, scrollToBottom]);
97+
}, [scrollState.autoScrollEnabled, scrollToBottom]);
9898

9999
useEffect(() => {
100100
const element = scrollRef.current;

client/src/components/ui/chat/message-loading.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
export default function MessageLoading() {
33
return (
44
<svg
5+
role="img"
6+
aria-label="Loading animation"
57
width="24"
68
height="24"
79
viewBox="0 0 24 24"

client/src/hooks/use-toast.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ export const reducer = (state: State, action: Action): State => {
9292
if (toastId) {
9393
addToRemoveQueue(toastId);
9494
} else {
95-
state.toasts.forEach((toast) => {
95+
for (const toast of state.toasts) {
9696
addToRemoveQueue(toast.id);
97-
});
97+
}
9898
}
9999

100100
return {
@@ -129,9 +129,9 @@ let memoryState: State = { toasts: [] };
129129

130130
function dispatch(action: Action) {
131131
memoryState = reducer(memoryState, action);
132-
listeners.forEach((listener) => {
132+
for (const listener of listeners) {
133133
listener(memoryState);
134-
});
134+
}
135135
}
136136

137137
type Toast = Omit<ToasterToast, "id">;
@@ -176,7 +176,7 @@ function useToast() {
176176
listeners.splice(index, 1);
177177
}
178178
};
179-
}, [state]);
179+
}, []);
180180

181181
return {
182182
...state,

client/src/hooks/use-version.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export default function useVersion() {
6060
}
6161
}
6262
} catch (e) {
63-
console.error("Unable to retrieve latest version from GitHub");
63+
console.error(`Unable to retrieve latest version from GitHub: ${e}`);
6464
}
6565
};
6666

client/src/lib/api.ts

+24-19
Original file line numberDiff line numberDiff line change
@@ -25,36 +25,41 @@ const fetcher = async ({
2525

2626
if (method === "POST") {
2727
if (body instanceof FormData) {
28-
// @ts-expect-error - Suppressing potentially undefined options header
29-
delete options.headers["Content-Type"];
28+
if (options.headers && typeof options.headers === 'object') {
29+
// Create new headers object without Content-Type
30+
options.headers = Object.fromEntries(
31+
Object.entries(options.headers as Record<string, string>)
32+
.filter(([key]) => key !== 'Content-Type')
33+
);
34+
}
3035
options.body = body;
3136
} else {
3237
options.body = JSON.stringify(body);
3338
}
3439
}
3540

3641
return fetch(`${BASE_URL}${url}`, options).then(async (resp) => {
37-
if (resp.ok) {
38-
const contentType = resp.headers.get("Content-Type");
39-
40-
if (contentType === "audio/mpeg") {
41-
return await resp.blob();
42-
}
43-
return resp.json();
42+
const contentType = resp.headers.get('Content-Type');
43+
if (contentType === "audio/mpeg") {
44+
return await resp.blob();
4445
}
4546

46-
const errorText = await resp.text();
47-
console.error("Error: ", errorText);
47+
if (!resp.ok) {
48+
const errorText = await resp.text();
49+
console.error("Error: ", errorText);
4850

49-
let errorMessage = "An error occurred.";
50-
try {
51-
const errorObj = JSON.parse(errorText);
52-
errorMessage = errorObj.message || errorMessage;
53-
} catch {
54-
errorMessage = errorText || errorMessage;
55-
}
51+
let errorMessage = "An error occurred.";
52+
try {
53+
const errorObj = JSON.parse(errorText);
54+
errorMessage = errorObj.message || errorMessage;
55+
} catch {
56+
errorMessage = errorText || errorMessage;
57+
}
5658

57-
throw new Error(errorMessage);
59+
throw new Error(errorMessage);
60+
}
61+
62+
return resp.json();
5863
});
5964
};
6065

client/src/lib/info.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"version": "0.1.9-alpha.1"}
1+
{"version": "0.1.9"}

client/src/main.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import { createRoot } from "react-dom/client";
33
import "./index.css";
44
import App from "./App.tsx";
55

6-
createRoot(document.getElementById("root")!).render(
6+
const rootElement = document.getElementById("root");
7+
8+
if (!rootElement) {
9+
throw new Error("Root element not found");
10+
}
11+
12+
createRoot(rootElement).render(
713
<StrictMode>
814
<App />
915
</StrictMode>

client/src/types.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Update the IAttachment interface
2+
export interface IAttachment {
3+
url: string;
4+
contentType?: string; // Make contentType optional
5+
title: string;
6+
}

client/vite.config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineConfig, loadEnv } from "vite";
22
import react from "@vitejs/plugin-react-swc";
33
import viteCompression from "vite-plugin-compression";
4-
import path from "path";
4+
import path from "node:path";
55

66
// https://vite.dev/config/
77
export default defineConfig(({ mode }) => {

packages/_examples/plugin-with-di/src/actions/sampleAction.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ const options: ActionOptions<CreateResourceContent> = {
9494
*/
9595
@injectable()
9696
export class CreateResourceAction extends BaseInjectableAction<CreateResourceContent> {
97-
constructor(
98-
@inject(SampleProvider)
99-
private readonly sampleProvider: SampleProvider
100-
) {
97+
private sampleProvider: SampleProvider;
98+
99+
constructor(sampleProvider: SampleProvider) {
101100
super(options);
101+
this.sampleProvider = sampleProvider;
102102
}
103103

104104
async validate(

packages/_examples/plugin-with-di/src/providers/sampleProvider.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ export class SampleProvider
2525
{
2626
private _sharedInstance: Record<string, string>;
2727

28-
constructor(
29-
@inject("DYNAMIC_DATA")
30-
private readonly dynamicData: Record<string, string>
31-
) {}
28+
private dynamicData: Record<string, string>;
29+
30+
constructor(dynamicData: Record<string, string>) {
31+
this.dynamicData = dynamicData;
32+
}
3233

3334
// ---- Implementing the InjectableProvider interface ----
3435

0 commit comments

Comments
 (0)