Imported from Dendekky/dendekky (
AGENTS.md). Install upstream withnpx skills add Dendekky/dendekky. Copyright stays with the author.
Agent notes — dendekky
Personal site for Ibrahim Adeniyi (Next.js App Router). Use this file to orient before editing.
Package manager
Use Bun for installs and scripts.
| Task | Command |
|---|---|
| Install deps | bun install |
| Dev server | bun run dev |
| Production build | bun run build |
| Start (after build) | bun run start |
| Lint | bun run lint (ESLint CLI — next lint was removed in Next.js 16) |
Lockfile: bun.lock. Prefer Bun over npm/yarn/pnpm in this repo.
Environment
.env.local(not committed):OPENAI_API_KEYfor the chat API. Optional:OPENAI_CHAT_MODEL(defaultgpt-4o-mini)..env.example: documents required variables.
Layout of important files
App Router (app/)
| Path | Role |
|---|---|
app/layout.tsx |
Root layout: metadata, SiteShell (nav, assistant, footer), JsonLd |
app/globals.css |
Global styles, Tailwind layers |
app/page.tsx |
Home |
app/blog/page.tsx |
Blog index |
app/blog/[slug]/page.tsx |
Blog post |
app/projects/page.tsx |
Projects |
app/resume/page.tsx |
Resume |
app/not-found.tsx |
404 |
app/robots.ts |
robots.txt |
app/sitemap.ts |
Sitemap |
app/api/chat/route.ts |
Streaming AI chat (OpenAI via AI SDK) |
app/actions/blog.ts |
Server actions: create/update/delete posts (dev-only guards) |
app/admin/layout.tsx |
Admin shell |
app/admin/blog/page.tsx |
Admin post list |
app/admin/blog/new/page.tsx |
New post |
app/admin/blog/edit/[slug]/page.tsx |
Edit post |
app/admin/blog/post-editor.tsx |
Markdown editor UI |
app/admin/blog/delete-button.tsx |
Delete control |
Components (components/)
| File | Role |
|---|---|
Navigation.tsx |
Site title link only (no section links; navigation via assistant + in-page links) |
AssistantNudge.tsx |
When assistant is collapsed: dismissible bubble toward open control (dendekky-assistant-hint-dismissed) |
Footer.tsx |
Footer + social |
AssistantChat.tsx |
AssistantProvider, in-flow mobile panel + desktop sidebar (client) |
BlogList.tsx |
Blog listing |
JsonLd.tsx |
Structured data |
admin/DevelopmentOnly.tsx |
Gates admin when not in development |
Data & lib
| File | Role |
|---|---|
data/config.ts |
siteUrl, SEO meta, hero, contact |
data/projects.ts |
Project list |
data/resume.ts |
Resume structured data |
lib/blog.ts |
Read/list markdown posts from content/blog |
lib/assistant-context.ts |
System prompt text for the chat assistant |
lib/assistant-tools.ts |
AI tools: listBlogArticles (server), navigate / openBlogArticle (client via addToolOutput) |
lib/assistant-client-tools.ts |
Path/slug validation for browser tools (client-safe) |
Content
| Path | Role |
|---|---|
content/blog/*.md |
Blog posts (front matter + markdown body) |
Config & tooling
| File | Role |
|---|---|
next.config.js |
Next.js config |
eslint.config.mjs |
ESLint flat config (Next 16 + TypeScript rules) |
tailwind.config.js |
Tailwind + typography plugin |
postcss.config.js |
PostCSS |
tsconfig.json |
TypeScript |
.prettierrc.js |
Prettier |
package.json |
Dependencies and scripts |
Legacy / optional
| Path | Role |
|---|---|
pages/api/hello.js |
Pages Router sample API (separate from App Router) |
Stack (high level)
- Next.js 16 (App Router, Turbopack in dev/build by default), React 19, TypeScript
- Tailwind CSS + @tailwindcss/typography
- Markdown blog:
gray-matter,remark,remark-html - Admin editor: EasyMDE /
react-simplemde-editor - AI chat:
ai,@ai-sdk/openai,@ai-sdk/react - URL state:
nuqs— assistant expanded state defaults to on (parseAsBoolean.withDefault(true)). Collapsing sets?assistant=false; when expanded again the param is cleared. SeeSiteShell+AssistantProvider/AssistantMobileSection/AssistantDesktopAsideincomponents/AssistantChat.tsx. Root layout usesNuqsAdapterandSuspense(required foruseSearchParamsduring static generation).
Conventions
- Public pages use
max-w-3xlcontent width (nav/footer aligned). - Blog CRUD in
app/actions/blog.tsis intended for local development only (NODE_ENV === 'development'). - Assistant answers should stay grounded in
lib/assistant-context.ts+ site data; API key is server-side only.