diff --git a/apps/web/components/chat/index.tsx b/apps/web/components/chat/index.tsx
index 70f01d062..1e29535d6 100644
--- a/apps/web/components/chat/index.tsx
+++ b/apps/web/components/chat/index.tsx
@@ -1612,11 +1612,11 @@ export function ChatSidebar({
]
for (const t of filtered) {
const ts = new Date(t.updatedAt).getTime()
- if (ts >= startOfToday) buckets[0].items.push(t)
- else if (ts >= startOfToday - day) buckets[1].items.push(t)
- else if (ts >= startOfToday - 7 * day) buckets[2].items.push(t)
- else if (ts >= startOfToday - 30 * day) buckets[3].items.push(t)
- else buckets[4].items.push(t)
+ if (ts >= startOfToday) buckets[0]?.items.push(t)
+ else if (ts >= startOfToday - day) buckets[1]?.items.push(t)
+ else if (ts >= startOfToday - 7 * day) buckets[2]?.items.push(t)
+ else if (ts >= startOfToday - 30 * day) buckets[3]?.items.push(t)
+ else buckets[4]?.items.push(t)
}
return buckets.filter((b) => b.items.length > 0)
}, [threads, historySearch])
diff --git a/apps/web/components/memory-graph/graph-card.tsx b/apps/web/components/memory-graph/graph-card.tsx
index de8bed3d2..083bb2862 100644
--- a/apps/web/components/memory-graph/graph-card.tsx
+++ b/apps/web/components/memory-graph/graph-card.tsx
@@ -67,15 +67,13 @@ export function StaticGraphPreview({
const result: { x1: number; y1: number; x2: number; y2: number }[] = []
const edgeCount = Math.min(nodes.length - 1, 20)
for (let i = 0; i < edgeCount; i++) {
- const a = Math.floor(rand() * nodes.length)
- let b = Math.floor(rand() * nodes.length)
- if (b === a) b = (a + 1) % nodes.length
- result.push({
- x1: nodes[a]?.x,
- y1: nodes[a]?.y,
- x2: nodes[b]?.x,
- y2: nodes[b]?.y,
- })
+ const aIdx = Math.floor(rand() * nodes.length)
+ let bIdx = Math.floor(rand() * nodes.length)
+ if (bIdx === aIdx) bIdx = (aIdx + 1) % nodes.length
+ const a = nodes[aIdx]
+ const b = nodes[bIdx]
+ if (!a || !b) continue
+ result.push({ x1: a.x, y1: a.y, x2: b.x, y2: b.y })
}
return result
}, [nodes])
diff --git a/apps/web/components/orbit-memory.tsx b/apps/web/components/orbit-memory.tsx
index 757d2a6df..8923da13f 100644
--- a/apps/web/components/orbit-memory.tsx
+++ b/apps/web/components/orbit-memory.tsx
@@ -48,7 +48,7 @@ const INTEG: {
key?: string
label?: string
sub?: string
- ring: number
+ ring: 0 | 1
ang: number
size: number
dim: boolean
@@ -76,8 +76,8 @@ const DW = 780
const DH = 1024
const CX = 390
const CY = 512
-const RR = [200, 335]
-const SPEED = [1.0, 0.78]
+const RR: [number, number] = [200, 335]
+const SPEED: [number, number] = [1.0, 0.78]
const DRAW: [number, number, number, string][] = [
[125, 0.28, 1.7, "#74a8f6"],
[200, 0.18, 1.9, "#4389ff"],
@@ -167,16 +167,15 @@ export default function OrbitMemory({
track.setAttribute("stroke-opacity", "0")
dtrack.setAttribute("stroke-opacity", "0")
for (let k = 0; k < NC; k++) {
- cms[k].setAttribute("opacity", "0")
- cmgs[k].setAttribute("opacity", "0")
- oms[k].setAttribute("opacity", "0")
- omgs[k].setAttribute("opacity", "0")
+ cms[k]?.setAttribute("opacity", "0")
+ cmgs[k]?.setAttribute("opacity", "0")
+ oms[k]?.setAttribute("opacity", "0")
+ omgs[k]?.setAttribute("opacity", "0")
}
}
let angle = 0
const place = () => {
- for (let i = 0; i < INTEG.length; i++) {
- const it = INTEG[i]
+ for (const [i, it] of INTEG.entries()) {
const a = ((it.ang + angle * SPEED[it.ring]) * Math.PI) / 180
const R = RR[it.ring]
const ux = CX + R * Math.cos(a)
@@ -199,8 +198,8 @@ export default function OrbitMemory({
const DISC = 700
const INN: number[] = []
const OUT: number[] = []
- for (let i = 0; i < INTEG.length; i++) {
- ;(INTEG[i].ring === 0 ? INN : OUT).push(i)
+ for (const [i, it] of INTEG.entries()) {
+ ;(it.ring === 0 ? INN : OUT).push(i)
}
let phase = "orbit"
let pT0 = 0
@@ -259,12 +258,16 @@ export default function OrbitMemory({
const ay = pyc - uy * HL
const bx = pxc + ux * HL
const by = pyc + uy * HL
- setLine(gr[k], ax, ay, bx, by)
- setLine(cr[k], ax, ay, bx, by)
- setLine(gl[k], ax, ay, bx, by)
+ const grad = gr[k]
+ const comet = cr[k]
+ const glow = gl[k]
+ if (!grad || !comet || !glow) continue
+ setLine(grad, ax, ay, bx, by)
+ setLine(comet, ax, ay, bx, by)
+ setLine(glow, ax, ay, bx, by)
const o = Math.sin(f * Math.PI) * P
- cr[k].setAttribute("opacity", o.toFixed(2))
- gl[k].setAttribute("opacity", (0.6 * o).toFixed(2))
+ comet.setAttribute("opacity", o.toFixed(2))
+ glow.setAttribute("opacity", (0.6 * o).toFixed(2))
}
}
const frame = (now: number) => {
@@ -276,13 +279,13 @@ export default function OrbitMemory({
if (phase === "orbit" && pt > ORBIT) {
phase = "receive"
pT0 = now
- src = INN[(ci * 5) % INN.length]
- dst = OUT[(ci * 7) % OUT.length]
+ src = INN[(ci * 5) % INN.length] ?? 0
+ dst = OUT[(ci * 7) % OUT.length] ?? 0
ci++
nodes[src]?.classList.add("sm-active")
stage.style.setProperty(
"--cm",
- `rgb(${ACCENT[INTEG[src].key!] || "91,157,255"})`,
+ `rgb(${ACCENT[INTEG[src]?.key ?? ""] || "91,157,255"})`,
)
} else if (phase === "receive" && pt > RECV) {
phase = "send"
@@ -318,8 +321,8 @@ export default function OrbitMemory({
seg(
now,
track,
- INTEG[src]._x!,
- INTEG[src]._y!,
+ INTEG[src]?._x ?? 0,
+ INTEG[src]?._y ?? 0,
ps,
grads,
cms,
@@ -330,8 +333,8 @@ export default function OrbitMemory({
seg(
now,
dtrack,
- INTEG[dst]._x!,
- INTEG[dst]._y!,
+ INTEG[dst]?._x ?? 0,
+ INTEG[dst]?._y ?? 0,
pd,
ogrs,
oms,
@@ -508,7 +511,9 @@ export default function OrbitMemory({
{it.sub}
@@ -518,7 +523,9 @@ export default function OrbitMemory({
)}
diff --git a/apps/web/components/settings/integrations.tsx b/apps/web/components/settings/integrations.tsx
index 355a51e12..a04db3838 100644
--- a/apps/web/components/settings/integrations.tsx
+++ b/apps/web/components/settings/integrations.tsx
@@ -152,7 +152,10 @@ export default function Integrations() {
name: `ios-${generateId().slice(0, 8)}`,
prefix: `sm_${org?.id}_`,
})
- return res.key
+ if (res.error)
+ throw new Error("Failed to create API key", { cause: res.error })
+ if (!res.data?.key) throw new Error("API key missing from response")
+ return res.data.key
},
onSuccess: (key) => {
setApiKey(key)
@@ -182,7 +185,7 @@ export default function Integrations() {
prefix: `sm_${org.id}_`,
})
if (res.error)
- throw new Error(res.error.message ?? "Failed to create API key")
+ throw new Error("Failed to create API key", { cause: res.error })
if (!res.data?.key) throw new Error("API key missing from response")
return res.data.key
},
diff --git a/apps/web/components/user-profile-menu.tsx b/apps/web/components/user-profile-menu.tsx
index ea034d733..1854cde8a 100644
--- a/apps/web/components/user-profile-menu.tsx
+++ b/apps/web/components/user-profile-menu.tsx
@@ -79,9 +79,11 @@ export function UserProfileMenu({
const initials = (() => {
if (user.name) {
const parts = user.name.trim().split(/\s+/)
+ const first = parts[0] ?? ""
+ const last = parts[parts.length - 1] ?? ""
return parts.length >= 2
- ? `${parts[0][0]}${parts[parts.length - 1][0]}`.toUpperCase()
- : parts[0].slice(0, 2).toUpperCase()
+ ? `${first.slice(0, 1)}${last.slice(0, 1)}`.toUpperCase()
+ : first.slice(0, 2).toUpperCase()
}
if (user.email) return user.email.slice(0, 2).toUpperCase()
return "SM"
diff --git a/apps/web/hooks/use-reset-organization.ts b/apps/web/hooks/use-reset-organization.ts
index 4c71580fb..f920d55ee 100644
--- a/apps/web/hooks/use-reset-organization.ts
+++ b/apps/web/hooks/use-reset-organization.ts
@@ -11,7 +11,7 @@ export function useResetOrganization() {
mutationFn: async (body: { confirmation: string }) => {
const res = await $fetch("@post/settings/reset", {
body,
- retry: { attempts: 0 },
+ retry: 0,
})
if (res.error) {
const e = res.error as Record
diff --git a/apps/web/stores/chat.ts b/apps/web/stores/chat.ts
index 456217b7f..f815bb826 100644
--- a/apps/web/stores/chat.ts
+++ b/apps/web/stores/chat.ts
@@ -27,8 +27,6 @@ export function areUIMessageArraysEqual(
return false
}
- if (msgA.content !== msgB.content) return false
-
if (JSON.stringify(msgA.parts) !== JSON.stringify(msgB.parts)) {
return false
}
@@ -202,7 +200,8 @@ export function usePersistentChat() {
)
const conversations: ConversationSummary[] = (() => {
- const convs = projectState?.conversations ?? {}
+ const convs: Record =
+ projectState?.conversations ?? {}
return Object.entries(convs).map(([id, rec]) => ({
id,
title: rec.title,
diff --git a/apps/web/stores/index.ts b/apps/web/stores/index.ts
index e13cccef6..85dd569a0 100644
--- a/apps/web/stores/index.ts
+++ b/apps/web/stores/index.ts
@@ -21,7 +21,7 @@ export function useProject() {
const normalizedProjects =
selectedProjects.length === 0 ? [defaultTag] : selectedProjects
- const selectedProject = normalizedProjects[0]
+ const selectedProject = normalizedProjects[0] ?? defaultTag
const effectiveContainerTags = normalizedProjects
diff --git a/packages/memory-graph/src/hooks/use-graph-data.ts b/packages/memory-graph/src/hooks/use-graph-data.ts
index aed2d6f01..71fd3a29f 100644
--- a/packages/memory-graph/src/hooks/use-graph-data.ts
+++ b/packages/memory-graph/src/hooks/use-graph-data.ts
@@ -507,8 +507,7 @@ export function useGraphData(
// Golden angle (~137.5 deg) produces optimal packing in a spiral
const goldenAngle = Math.PI * (3 - Math.sqrt(5))
- for (let docIdx = 0; docIdx < docCount; docIdx++) {
- const doc = documents[docIdx]
+ for (const [docIdx, doc] of documents.entries()) {
const docCluster = getDocumentClusterAssignment(doc, clusterAssignments)
const angle = docIdx * goldenAngle
const radius = spiralScale * Math.sqrt((docIdx + 1) / docCount)
diff --git a/packages/ui/assets/icons.tsx b/packages/ui/assets/icons.tsx
index 7aaece871..035328661 100644
--- a/packages/ui/assets/icons.tsx
+++ b/packages/ui/assets/icons.tsx
@@ -1,3 +1,5 @@
+import type { CSSProperties } from "react"
+
export const OneDrive = ({ className }: { className?: string }) => (
)
-export const SyncLogoIcon = ({ className }: { className?: string }) => {
+export const SyncLogoIcon = ({
+ className,
+ style,
+}: {
+ className?: string
+ style?: CSSProperties
+}) => {
return (