Skip to content

Commit 90393c0

Browse files
committed
feat: enhance frontend module organization and error handling
- Updated `CLAUDE.md` to clarify the frontend module layout, emphasizing co-location of components, hooks, and stores for better feature cohesion. - Refactored imports in various components to align with the new module structure, ensuring consistency across the application. - Introduced translation support in the `ErrorBoundary` component for improved user experience during error handling. - Deleted unused files and optimized imports to streamline the codebase.
1 parent 988d417 commit 90393c0

43 files changed

Lines changed: 1122 additions & 1099 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ cargo build # Standalone Rust build when not using npm wrapper
146146
- Rust 2021 edition, standard module layout
147147
- TypeScript strict mode
148148
- No default exports (use named exports)
149+
- **Frontend module layout (co-location is intentional)**: `src/` is organized top-level by responsibility (`components/` `hooks/` `stores/` `lib/` `pages/` `locales/` `styles/`), and `components/` by feature (`ui/` shadcn primitives, `layout/` shell chrome, `chat/` the chat feature tree). **Co-locate a feature's `.tsx`, `.ts` helpers, and hooks together inside its feature folder** (e.g. `components/chat/composer/MessageInput.tsx` beside `attachmentUtils.ts`, `useComposerTextSelection.ts`) — this is deliberate feature cohesion, not "mixing"; do **not** split them out into separate `lib/services/hooks` trees. Cross-cutting hooks that serve the whole app live in `hooks/`; feature-specific hooks stay co-located. **Store imports are always direct** (`@/stores/<name>-store`); there is intentionally no `stores/` barrel.
149150
- **Frontend UI/UX**: Any time you author or refactor React UI or styling (`src/**/*.tsx`, shared CSS tokens, shell layout), **read and comply with** the project’s UI specs (they are complementary, not optional pick-one):
150151
- **Path-scoped reinforcement** (loads when editing matching files—reduces “forgot to load CLAUDE” cases):
151152
- **Cursor**: `.cursor/rules/misaka-frontend-ui-specs.mdc` (`globs`: `src/**/*.tsx`, `src/**/*.css`, `src/*.css`)

agent/_probe_winconsole.py

Lines changed: 0 additions & 48 deletions
This file was deleted.

agent/app/config.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,3 @@ def bridge_provider_api_keys(settings_obj: Settings | None = None) -> None:
7777
bridged.append("OPENAI_API_KEY")
7878
if bridged:
7979
logger.info("Bridged provider API keys into process env: %s", ", ".join(bridged))
80-
81-
82-
settings = Settings()

agent/app/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from fastapi import FastAPI
77

8-
from app.config import bridge_provider_api_keys, settings
8+
from app.config import bridge_provider_api_keys, get_settings
99
from app.dependencies import close_checkpointer, setup_checkpointer
1010
from app.routers.agent import router as agent_router
1111
from app.routers.health import router as health_router
@@ -29,7 +29,7 @@ async def lifespan(application: FastAPI):
2929
title="MisakaX Agent",
3030
version="0.1.0",
3131
description="MisakaX Agent Sidecar - LangGraph + PowerMem",
32-
debug=settings.debug,
32+
debug=get_settings().debug,
3333
lifespan=lifespan,
3434
)
3535

agent/app/models.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,29 @@ class InfoResponse(BaseModel):
110110
powermem_available: bool = False
111111

112112
model_config = {"frozen": False, "extra": "ignore"}
113+
114+
115+
# --------------------------------------------------------------------------- #
116+
# Memory models
117+
# --------------------------------------------------------------------------- #
118+
119+
class MemoryItem(BaseModel):
120+
"""A single normalized memory entry returned by the memory REST API."""
121+
122+
id: str | None = None
123+
content: str = ""
124+
score: float | None = None
125+
created_at: str | None = None
126+
metadata: dict[str, Any] = Field(default_factory=dict)
127+
128+
model_config = {"frozen": False, "extra": "ignore"}
129+
130+
131+
class MemoryListResponse(BaseModel):
132+
"""Paginated list of memory items."""
133+
134+
items: list[MemoryItem]
135+
offset: int = 0
136+
limit: int = 20
137+
138+
model_config = {"frozen": False, "extra": "ignore"}

agent/app/routers/memory.py

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,14 @@
66
from typing import Any
77

88
from fastapi import APIRouter, HTTPException, Query
9-
from pydantic import BaseModel, Field
109

1110
from app.memory import get_memory_engine
11+
from app.models import MemoryItem, MemoryListResponse
1212

1313
router = APIRouter(prefix="/memory", tags=["memory"])
1414
logger = logging.getLogger(__name__)
1515

1616

17-
class MemoryItem(BaseModel):
18-
id: str | None = None
19-
content: str = ""
20-
score: float | None = None
21-
created_at: str | None = None
22-
metadata: dict[str, Any] = Field(default_factory=dict)
23-
24-
25-
class MemoryListResponse(BaseModel):
26-
items: list[MemoryItem]
27-
offset: int = 0
28-
limit: int = 20
29-
30-
3117
def _require_engine() -> Any:
3218
engine = get_memory_engine()
3319
if engine is None:

agent/run.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,13 @@ def _get_windows_console_stream(_stream, _encoding, _errors): # noqa: ANN001, A
6262

6363
import uvicorn # noqa: E402 (import after DLL dir registration)
6464

65-
from app.config import settings # noqa: E402
65+
from app.config import get_settings # noqa: E402
6666
from app.main import app # noqa: E402
6767

6868

6969
def main() -> None:
7070
multiprocessing.freeze_support()
71+
settings = get_settings()
7172
uvicorn.run(
7273
app,
7374
host=settings.host,

0 commit comments

Comments
 (0)