Imported from YRootLab/OnMaru-Frontend (
AGENTS.md). Install upstream withnpx skills add YRootLab/OnMaru-Frontend. Copyright stays with the author.
Architecture
Data flows in, not out
- A component that renders UI must not own
fetch()/API calls inside its body. Data comes in from outside — as props from a parent (ideally a Server Component that fetched it), or as the return value of a dedicated hook. - Prefer fetching in the page-level Server Component (
app/**/page.tsx) and passing the result down as props. Reach for client-side fetching only when the data depends on client-only state a server render can't know in advance (a filter, a user action, a live poll). - When client-side fetching is unavoidable, isolate it in a
features/<feature>/hooks/use<Thing>.tshook that owns thefetch/loading/error state and returns plain data (seesrc/features/hanok-archive/hooks/*for the existing shape:{ data, loading }or similar). The rendering component calls the hook and stays a pure function of its inputs — reusable and testable without a live network. - Non-fetch business logic (mapping, decoding, classification) that more than one place needs belongs in
features/<feature>/services/*.ts, not copy-pasted into a component. - Refactors that only relocate data-fetching/logic into a hook or service must not change the rendered output, animation, or styling of the component they're extracted from — verify with a type-check and a visual diff before considering the extraction done.
Clean architecture boundaries
- Organize new or migrated feature code as
features/<feature>/{domain,application,infrastructure,presentation}. Migrate incrementally; do not require an all-at-once directory move. domaincontains framework-independent entities, value types, and deterministic business rules. It must not import React, Next.js, browser APIs, network clients, or infrastructure modules.applicationcontains use cases and the interfaces (ports) they need. It may importdomain, but not concrete HTTP, storage, browser, or React implementations.infrastructureimplements application ports for HTTP clients, external SDKs, browser storage, and fixtures. It may importapplicationcontracts anddomaintypes, but neverpresentation.presentationcontains React components, hooks, and route-facing view models. It invokes application use cases and receives concrete infrastructure implementations through a composition boundary; it must not contain business rules or direct external API calls.- Next.js pages and route handlers are composition boundaries: they may select infrastructure implementations, create use cases, and pass data or callbacks into presentation code.
- Dependencies must point inward only:
presentation -> application -> domainandinfrastructure -> application/domain. Tests may substitute port implementations with deterministic fakes.
UI design guidance
Color direction
- Do not introduce warm beige, cream, yellow, parchment, or sepia tones as a default surface treatment. They make the product feel overly themed and artificial.
- Prefer neutral gray surfaces for page canvases, cards, hover states, empty states, and loading placeholders. Use colors such as
#f8f8f7,#f5f5f4,#e5e5e3,#d9d9d7, and#cdcdcaas the starting palette. - Preserve established semantic and interaction colors. Do not replace active, selected, warning, or brand colors merely to make a surface neutral.
- If a warm tone is genuinely required by existing brand or content imagery, keep it local to that component and do not spread it to surrounding surfaces.
Typography hierarchy
- In all views and components, the Main Title must always be placed at the very top, and Subtitles, descriptions, and secondary metadata must be placed below the title. Do not place subtitles above main titles.
Loading states
- Skeletons must reserve the exact final dimensions, thumbnail aspect ratios, title/subtitle lines, controls, padding, and overall card/container footprint as the fully-loaded UI. Skeletons must match the real response layout 1:1 so that content never shrinks, grows, shifts, or jumps (zero Layout Shift / CLS) when data arrives.
- Skeletons and live data components must share synchronized dimension tokens and container heights to prevent downstream layout shifts and scroll reveal triggers from misfiring.
- Use neutral gray skeleton colors and a restrained shimmer. Avoid warm/yellow skeleton fills.
Scroll reveal transitions
- Apply the section reveal only to content the visitor has not yet seen in the current page session.
- On a page reload, sections at or above the current scroll position must render in their final state without a replayed shrink-to-grow animation.
- Once a section has been revealed, keep its final state while scrolling back upward; do not fold and replay it.
- Respect
prefers-reduced-motionand keep unsupported animation paths functionally identical without motion.
Shared agent workflow
AGENTS.mdis the shared source of truth for Copilot, Codex, Claude, Gemini, Cline, and other agents. Every agent must read and follow it before making changes; keep harness-specific entry files thin.- Treat source files as canonical. Do not edit generated output unless the task explicitly requires it.
- Before claiming completion, committing, or releasing, run fresh verification appropriate to the touched code.
- Record resumable work in
handoff.md, deferred follow-ups inimprovements.md, and human-readable meaningful changes inchangelog.md. - Confirm exact targets before destructive operations. Do not delete, overwrite, or reset user work without explicit approval.
Work tracking
- GitHub Issues are the Source of Truth for triaged, actionable work.
- Keep
project-roadmap.mdlimited to long-term Vision and milestone-level goals. - When the user raises an ad hoc request, record it immediately in
handoff.mdif it affects current-session continuity, or inimprovements.mdif it is an untriaged follow-up idea. Issue creation is not required at capture time. - During triage, keep a local note, link it to an existing Issue, promote it to a new Issue, or remove it only when completion is verified.
- Immediately before creating a Pull Request, invoke
cleaning-work-logsand reconcile the branch, work logs, related Issues, and PR description. - Immediately before merge, invoke
cleaning-work-logsagain because PR and Issue state may have changed during review. - Every PR must reference its related Issue. Use an auto-close keyword only when that PR's merge target should actually close the Issue.
- Before closing an Issue, verify its acceptance criteria and merge state.
Git Flow branch policy
- Integration branch:
develop. - Production branch:
master. - Work branches:
feature/*,feat/*,fix/*, anddocs/*merge intodevelopthrough a pull request. - Release branches:
release/*merge intomasterthrough a pull request, then merge back intodevelop. - Emergency fixes:
hotfix/*merge intomasterthrough a pull request, then merge back intodevelop. - Direct pushes, force pushes, and unreviewed merges to
developormasterare prohibited. - After finishing development work, agents must not create a PR or merge on their own — always get the user's final approval first.
- Required CI checks must pass and the branch must be current before every merge. Shared changes require at least one approval.
- Create semantic version tags such as
v0.3.2only frommasterafter the release merge. - Pushes to
developdeploy preview/staging builds. Pushes tomasterand semanticv*tags deploy Production through.github/workflows/deploy.yml. - Delete short-lived branches after merge. Release automation must use least-privilege permissions and avoid workflow loops.
Core UI package (in-repo)
src/private/core-uiis a regular directory in this repository. It was previously a Git submodule referencing the privateYRootLab/onmaru-core-uirepository, but that reference was removed so the code is committed directly here (the original repository remains archived).- No submodule initialization, deploy keys, or extra authentication are required for local development, CI, or Vercel deployments.
- Do not record private submodule access permissions or authentication tokens in source code, logs, or documentation.
- When modifying files inside
src/private/core-ui, commit and push them in this repository like any other source file. Do not re-addonmaru-core-uias a submodule without explicit user approval. - Core UI components are imported via
@/private/core-ui/*. AModule not found: Can't resolve '@/private/core-ui/...'error is now a real code bug — check that the file exists insrc/private/core-ui.
This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in node_modules/next/dist/docs/ (resolved from this file's directory; in monorepos the next package may not be visible from the repo root) before writing any code. Heed deprecation notices.
This block is written and re-added by next dev — verify at node_modules/next/dist/server/lib/generate-agent-files.js. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.
