Never edit .npmrc directly in product repos — managed by canonical template in learning_ai_common_plat/scripts/npmrc.template. Use sync-npmrc.sh to propagate. Prevents gitea.bytelyst.com hardcoding.
322 lines
19 KiB
Markdown
322 lines
19 KiB
Markdown
# AGENTS.md — AI Coding Agent Instructions
|
|
|
|
> **For:** Claude Code, OpenAI Codex, Cursor, GitHub Copilot, Windsurf Cascade, and any AI coding agent.
|
|
> **Repo:** `learning_ai_notes` — NoteLett structured notes platform for humans and AI agents.
|
|
> **See also:** [`docs/PRD.md`](docs/PRD.md) for full product spec, [`docs/ROADMAP.md`](docs/ROADMAP.md) for implementation plan.
|
|
|
|
---
|
|
|
|
## 1. Project Identity
|
|
|
|
| Key | Value |
|
|
|-----|-------|
|
|
| **Product** | NoteLett |
|
|
| **Product ID** | `notelett` |
|
|
| **Bundle ID (iOS)** | `com.bytelyst.notelett` |
|
|
| **Bundle ID (Android)** | `com.notelett.app` |
|
|
| **Domain** | notelett.app |
|
|
| **Repo** | `learning_ai_notes` |
|
|
| **Ecosystem** | ByteLyst (shares platform-service with LysnrAI, MindLyst, ChronoMind, JarvisJr, NomGap, PeakPulse) |
|
|
|
|
## 2. Repo Layout
|
|
|
|
```
|
|
learning_ai_notes/
|
|
├── backend/ # Fastify 5 + TypeScript ESM backend (port 4016)
|
|
│ ├── src/
|
|
│ │ ├── lib/
|
|
│ │ │ ├── config.ts # Zod-validated env config
|
|
│ │ │ ├── product-config.ts # Product identity from shared/product.json
|
|
│ │ │ ├── auth.ts # JWT extraction helper
|
|
│ │ │ ├── request-context.ts # getUserId(req), getRequestProductId(req)
|
|
│ │ │ ├── cosmos-init.ts # Cosmos container registration
|
|
│ │ │ ├── datastore.ts # @bytelyst/datastore provider (Cosmos or memory)
|
|
│ │ │ ├── errors.ts # Re-export from @bytelyst/errors
|
|
│ │ │ ├── llm.ts # @bytelyst/llm lazy singleton
|
|
│ │ │ ├── copilot-transform.ts # Copilot text transforms (shorten, expand, bulletize, etc.)
|
|
│ │ │ ├── embeddings.ts # Embedding utilities (duplicate detection, related notes)
|
|
│ │ │ ├── feature-flags.ts # 20 feature flags (core + Smart Actions)
|
|
│ │ │ ├── telemetry.ts # Telemetry event buffer
|
|
│ │ │ └── field-encrypt.ts # @bytelyst/field-encrypt singleton
|
|
│ │ ├── modules/
|
|
│ │ │ ├── notes/ # Note CRUD (types, repository, routes, test)
|
|
│ │ │ ├── workspaces/ # Workspace CRUD (types, repository, routes, test)
|
|
│ │ │ ├── note-relationships/ # Note linking (types, repository, routes, test)
|
|
│ │ │ ├── note-tasks/ # Task CRUD (types, repository, routes, test)
|
|
│ │ │ ├── note-artifacts/ # Artifact CRUD (types, repository, routes, test)
|
|
│ │ │ ├── note-agent-actions/ # Agent action audit trail + batch review (types, repository, routes, test)
|
|
│ │ │ ├── saved-views/ # Persisted saved views CRUD (types, repository, routes)
|
|
│ │ │ └── note-prompts/ # Smart Actions: prompt templates, runner, scheduler, webhooks
|
|
│ │ │ ├── types.ts # PromptTemplateDoc, CRUD + Run schemas
|
|
│ │ │ ├── repository.ts # Prompt template CRUD
|
|
│ │ │ ├── routes.ts # Template CRUD + run + reading-time + suggest-tags + duplicates + links + compare + merge + URL extract + knowledge gaps
|
|
│ │ │ ├── runner.ts # executePrompt() with retry + timeout
|
|
│ │ │ ├── scheduler.ts # Cron schedules + webhook triggers + routes
|
|
│ │ │ └── seed.ts # 20 built-in prompt templates
|
|
│ │ ├── mcp/
|
|
│ │ │ ├── note-tool-contracts.ts # 8 MCP tool Zod schemas + definitions
|
|
│ │ │ ├── note-tools.ts # 8 executable MCP tool implementations
|
|
│ │ │ ├── register-note-tools.ts # Fastify plugin to register MCP tools
|
|
│ │ │ └── *.test.ts # MCP test files
|
|
│ │ └── server.ts # Fastify entrypoint (11 route modules + MCP + scheduler)
|
|
│ ├── package.json
|
|
│ └── tsconfig.json
|
|
│
|
|
├── web/ # Next.js 16 + React 19 web app (App Router)
|
|
│ ├── src/
|
|
│ │ ├── app/
|
|
│ │ │ ├── page.tsx # Landing page
|
|
│ │ │ ├── layout.tsx # Root layout
|
|
│ │ │ └── (app)/ # Authenticated route group
|
|
│ │ │ ├── dashboard/ # Dashboard with metrics + recent notes
|
|
│ │ │ ├── workspaces/ # Workspace list + filters
|
|
│ │ │ ├── search/ # Search with saved queries
|
|
│ │ │ ├── reviews/ # Approval queue + agent timeline
|
|
│ │ │ └── notes/[noteId]/ # Note detail with editor
|
|
│ │ ├── components/ # React UI components
|
|
│ │ │ ├── Sidebar.tsx
|
|
│ │ │ ├── AppShell.tsx
|
|
│ │ │ ├── MetadataPanel.tsx
|
|
│ │ │ ├── LinkedNotesPanel.tsx
|
|
│ │ │ ├── AgentTimeline.tsx
|
|
│ │ │ ├── CreateNoteModal.tsx # Create note modal (workspace, title, body, tags)
|
|
│ │ │ └── LinkNoteModal.tsx # Link note relationship modal
|
|
│ │ └── lib/ # Pure TS clients + config
|
|
│ │ ├── product-config.ts # Product identity + API URLs
|
|
│ │ ├── api-helpers.ts # Shared getAccessToken() + createNotesApiClient()
|
|
│ │ ├── auth.ts # @bytelyst/react-auth provider
|
|
│ │ ├── notes-client.ts # Notes API client (backend)
|
|
│ │ ├── review-client.ts # Approval queue, timeline, batch review
|
|
│ │ ├── saved-views-client.ts # Saved views CRUD client
|
|
│ │ ├── platform.ts # @bytelyst/platform-client
|
|
│ │ ├── telemetry.ts # @bytelyst/telemetry-client
|
|
│ │ ├── diagnostics.ts # @bytelyst/diagnostics-client
|
|
│ │ ├── feature-flags.ts # @bytelyst/feature-flag-client
|
|
│ │ ├── kill-switch.ts # @bytelyst/kill-switch-client
|
|
│ │ ├── extraction-client.ts # Extraction-service task extraction
|
|
│ │ ├── blob-client.ts # @bytelyst/blob-client wrapper
|
|
│ │ ├── use-keyboard-shortcuts.ts # Global keyboard shortcuts hook
|
|
│ │ ├── use-debounce.ts # Debounce hook for search
|
|
│ │ └── types.ts # Shared TypeScript interfaces
|
|
│ ├── package.json
|
|
│ └── tsconfig.json
|
|
│
|
|
├── mobile/ # React Native + Expo companion app
|
|
│ ├── src/
|
|
│ │ ├── app/ # Expo Router screens
|
|
│ │ │ ├── (tabs)/ # 4-tab navigator (home, inbox, capture, settings)
|
|
│ │ │ ├── note/[noteId].tsx # Note detail
|
|
│ │ │ └── auth.tsx # Auth screen
|
|
│ │ ├── api/ # API clients
|
|
│ │ │ ├── config.ts # Product identity + API URLs
|
|
│ │ │ ├── auth.ts # @bytelyst/auth-client
|
|
│ │ │ ├── notes.ts # Notes API client
|
|
│ │ │ └── note-agent-actions.ts # Agent actions API client
|
|
│ │ ├── lib/ # Platform SDK wrappers
|
|
│ │ │ └── platform.ts # Telemetry, feature flags, kill switch, blob client
|
|
│ │ ├── store/ # Zustand stores
|
|
│ │ │ ├── auth-store.ts
|
|
│ │ │ ├── inbox-store.ts
|
|
│ │ │ ├── workspace-store.ts
|
|
│ │ │ ├── notes-store.ts
|
|
│ │ │ └── mmkv-storage.ts # MMKV persistent storage
|
|
│ │ └── theme/ # Design tokens
|
|
│ ├── app.json # Expo config
|
|
│ └── package.json
|
|
│
|
|
├── shared/
|
|
│ └── product.json # Canonical product identity
|
|
│
|
|
├── docs/
|
|
│ ├── PRD.md # Product requirements
|
|
│ ├── ROADMAP.md # Master execution tracker
|
|
│ ├── ARCHITECTURE_REVIEW_AND_REUSE_ROADMAP.md
|
|
│ └── roadmaps/ # Per-workstream roadmaps
|
|
│ ├── 00_MASTER_EXECUTION_PLAN.md
|
|
│ ├── 01_FOUNDATIONS_AND_DECISIONS.md
|
|
│ ├── 02_BACKEND_ROADMAP.md
|
|
│ ├── 03_WEB_ROADMAP.md
|
|
│ └── 04_MOBILE_ROADMAP.md
|
|
│
|
|
├── backend/Dockerfile # Multi-stage Docker build for backend
|
|
├── web/Dockerfile # Multi-stage Docker build for web
|
|
├── docker-compose.yml # Backend (4016) + web (3000)
|
|
├── scripts/docker-prep.sh # Pack @bytelyst/* tarballs for Docker
|
|
├── .github/workflows/ci.yml # GitHub Actions CI (backend + web + mobile)
|
|
├── AGENTS.md # This file
|
|
└── README.md
|
|
```
|
|
|
|
## 3. Tech Stack
|
|
|
|
| Layer | Technology |
|
|
|-------|-----------|
|
|
| **Backend** | Fastify 5, TypeScript ESM, Zod, jose (JWT), @bytelyst/datastore (Cosmos or memory) |
|
|
| **Web** | Next.js 16 (App Router), React 19, TailwindCSS v4, Zustand, Vitest |
|
|
| **Mobile** | React Native (Expo), TypeScript, expo-router, Zustand, MMKV |
|
|
| **Shared packages** | `@bytelyst/fastify-core`, `@bytelyst/config`, `@bytelyst/cosmos`, `@bytelyst/errors`, `@bytelyst/datastore`, `@bytelyst/api-client`, `@bytelyst/react-auth`, `@bytelyst/auth-client`, `@bytelyst/telemetry-client`, `@bytelyst/diagnostics-client`, `@bytelyst/feature-flag-client`, `@bytelyst/kill-switch-client`, `@bytelyst/platform-client`, `@bytelyst/blob-client` |
|
|
| **Design system** | `@bytelyst/design-tokens` (CSS custom properties), `@bytelyst/ui` (shared React components) |
|
|
| **Platform** | platform-service (port 4003) for auth, flags, telemetry, billing, blob |
|
|
| **Extraction** | extraction-service (port 4005) for AI-powered task extraction |
|
|
| **Database** | Azure Cosmos DB via `@bytelyst/datastore` — `productId: "notelett"` |
|
|
| **LLM** | `@bytelyst/llm` (mock/openai/azure providers), retry + timeout hardening |
|
|
| **Tests** | Vitest — 192 backend tests (32 files), 45 web tests (11 files), 50 mobile tests (10 files), 9 Playwright E2E specs |
|
|
|
|
## 4. Coding Conventions
|
|
|
|
### MUST follow
|
|
|
|
- Every Cosmos document MUST include a `productId: "notelett"` field
|
|
- Backend modules follow `types.ts` → `repository.ts` → `routes.ts` pattern
|
|
- All repositories use `@bytelyst/datastore` getCollection() — never direct Cosmos SDK calls
|
|
- Web engine logic in `web/src/lib/` — pure TS, no React imports
|
|
- Web components in `web/src/components/` — React UI only
|
|
- Mobile API clients in `mobile/src/api/` — pure TS
|
|
- Theme tokens use `--nl-*` CSS custom properties (web) or `NoteLettTheme` (native)
|
|
- Commit messages: `type(scope): description` — types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`
|
|
- Use `@bytelyst/ui` components (Button, Card, Badge, Toast, etc.) — never build custom equivalents
|
|
- All colors via `--nl-*` CSS custom properties from `@bytelyst/design-tokens` — never hardcode hex values
|
|
- Every interactive element must have `aria-label` or visible text label
|
|
|
|
|
|
### .npmrc — NEVER edit directly
|
|
|
|
**`.npmrc` is managed by a canonical template in `learning_ai_common_plat`.** Never create or hand-edit `.npmrc` — it will drift.
|
|
|
|
- **Template:** `../learning_ai_common_plat/scripts/npmrc.template`
|
|
- **Sync:** `cd ../learning_ai_common_plat && bash scripts/sync-npmrc.sh`
|
|
- **Key rule:** Never hardcode `gitea.bytelyst.com` — use `${GITEA_NPM_HOST:-localhost}:3300` (SSH tunnel on corp network)
|
|
|
|
### MUST NOT do
|
|
|
|
- Never use `console.log` in production code — use `req.log` or `app.log` in Fastify
|
|
- Never use `any` type — use Zod inference or explicit types
|
|
- Never hardcode colors — use theme tokens
|
|
- Never hardcode API URLs — use env vars or config
|
|
- Never hardcode product ID — use `PRODUCT_ID` from `product-config.ts`
|
|
- Never modify tests to make them pass — fix the actual code
|
|
- Never delete existing comments or documentation unless explicitly asked
|
|
- Never add emojis to code unless explicitly asked
|
|
|
|
## 5. Key Design Decisions
|
|
|
|
### MCP Tool Architecture
|
|
- 8 MCP tools: list, get, search, create_draft, update, link_notes, extract_tasks, attach_artifact
|
|
- Every write tool records an agent action audit trail
|
|
- All tools enforce product scope and user authentication
|
|
- Dry-run, idempotency key, and correlation ID support on all write tools
|
|
|
|
### Datastore Abstraction
|
|
- `@bytelyst/datastore` provides `CosmosDatastoreProvider` and `MemoryDatastoreProvider`
|
|
- `DB_PROVIDER` env var controls which provider is used (default: cosmos, test: memory)
|
|
- All 7 repositories use `getCollection()` — no direct Cosmos SDK calls
|
|
|
|
### Agent Action Audit Trail
|
|
- Every MCP tool write operation creates a `NoteAgentActionDoc` record
|
|
- Actions track: actorId, actorType, toolName, actionType, state, reason, before/after summaries
|
|
- Supports approval workflows: draft → proposed → approved/rejected → applied
|
|
|
|
### Cosmos Containers
|
|
- `notes` (partition: `/workspaceId`)
|
|
- `workspaces` (partition: `/userId`)
|
|
- `note_relationships` (partition: `/workspaceId`)
|
|
- `note_tasks` (partition: `/workspaceId`)
|
|
- `note_artifacts` (partition: `/workspaceId`)
|
|
- `note_agent_actions` (partition: `/workspaceId`)
|
|
- `saved_views` (partition: `/userId`)
|
|
- `note_prompts` (partition: `/userId`)
|
|
- `note_prompt_schedules` (partition: `/userId`)
|
|
- `note_prompt_webhooks` (partition: `/userId`)
|
|
|
|
## 6. Build & Test Commands
|
|
|
|
```bash
|
|
# ── Backend ────────────────────────────────────────
|
|
pnpm --filter @notelett/backend run dev # Dev server (port 4016)
|
|
pnpm --filter @notelett/backend run typecheck # tsc --noEmit
|
|
pnpm --filter @notelett/backend run test # backend Vitest tests
|
|
|
|
# ── Web ────────────────────────────────────────────
|
|
pnpm --filter @notelett/web run dev # Dev server (port 3000)
|
|
pnpm --filter @notelett/web run build # Production build
|
|
pnpm --filter @notelett/web run typecheck # tsc --noEmit
|
|
pnpm --filter @notelett/web run test # web Vitest tests
|
|
|
|
# ── Mobile ─────────────────────────────────────────
|
|
pnpm --filter @notelett/mobile run start # Expo dev server
|
|
pnpm --filter @notelett/mobile run typecheck # tsc --noEmit
|
|
pnpm --filter @notelett/mobile run test # mobile tests
|
|
|
|
# ── Full verification ──────────────────────────────
|
|
pnpm run verify
|
|
```
|
|
|
|
## 7. Backend API Endpoints
|
|
|
|
| Method | Path | Description |
|
|
|--------|------|-------------|
|
|
| GET/POST | `/api/notes` | List / create notes |
|
|
| GET/PATCH | `/api/notes/:id` | Note CRUD |
|
|
| POST | `/api/notes/:id/archive` | Archive note |
|
|
| POST | `/api/notes/:id/restore` | Restore note |
|
|
| POST | `/api/notes/:id/summarize` | Summarize note via extraction-service |
|
|
| GET | `/api/notes/export` | Export notes (JSON or Markdown) |
|
|
| GET | `/api/notes/search` | Search notes |
|
|
| GET/POST | `/api/workspaces` | List / create workspaces |
|
|
| GET/PATCH | `/api/workspaces/:id` | Workspace CRUD |
|
|
| GET/POST | `/api/note-relationships` | List / create relationships |
|
|
| GET/POST | `/api/note-tasks` | List / create tasks |
|
|
| GET/PATCH | `/api/note-tasks/:id` | Task CRUD |
|
|
| GET/POST | `/api/note-artifacts` | List / create artifacts |
|
|
| PATCH | `/api/note-artifacts/:id` | Update artifact |
|
|
| GET/POST | `/api/note-agent-actions` | List / create agent actions |
|
|
| PATCH | `/api/note-agent-actions/:id` | Update agent action state |
|
|
| POST | `/api/note-agent-actions/batch-review` | Batch approve/reject (up to 50) |
|
|
| GET/POST | `/api/saved-views` | List / create saved views |
|
|
| GET/PATCH/DELETE | `/api/saved-views/:id` | Saved view CRUD |
|
|
| POST | `/api/notes/:id/copilot` | Copilot text transform (shorten, expand, bulletize, etc.) |
|
|
| POST | `/api/notes/:id/suggest-title` | AI-generated title suggestion |
|
|
| POST | `/api/notes/:id/suggest-tags` | AI-generated tag suggestions |
|
|
| POST | `/api/notes/:id/check-duplicates` | Duplicate/similar note detection |
|
|
| POST | `/api/notes/:id/suggest-links` | Related note suggestions |
|
|
| POST | `/api/notes/compare` | Compare 2-5 notes via LLM |
|
|
| POST | `/api/notes/merge` | Merge 2-10 notes via LLM |
|
|
| POST | `/api/notes/chat` | Workspace RAG chat |
|
|
| GET/POST | `/api/note-prompts` | List / create prompt templates |
|
|
| GET/PATCH/DELETE | `/api/note-prompts/:id` | Template CRUD |
|
|
| POST | `/api/note-prompts/run` | Run a prompt template against a note |
|
|
| POST | `/api/note-prompts/url-extract` | Extract + summarize URL content |
|
|
| GET/POST | `/api/prompt-schedules` | List / create scheduled actions |
|
|
| GET/PATCH/DELETE | `/api/prompt-schedules/:id` | Schedule CRUD |
|
|
| GET | `/api/prompt-schedules/diagnostics` | Scheduler health |
|
|
| GET/POST | `/api/prompt-webhooks` | List / create webhook triggers |
|
|
| GET/PATCH/DELETE | `/api/prompt-webhooks/:id` | Webhook CRUD |
|
|
| POST | `/api/prompt-webhooks/:id/trigger` | Manually trigger a webhook |
|
|
| POST | `/api/workspaces/:wsId/knowledge-gaps` | Knowledge gap detection |
|
|
| GET | `/api/notes/:id/reading-time` | Reading time estimate |
|
|
| GET | `/health` | Health check |
|
|
|
|
## 8. MCP Tools
|
|
|
|
| Tool Name | Description | Role |
|
|
|-----------|-------------|------|
|
|
| `notes.notes.list` | List notes in a workspace | viewer |
|
|
| `notes.notes.get` | Get a single note | viewer |
|
|
| `notes.notes.search` | Search notes with lexical query | viewer |
|
|
| `notes.notes.create_draft` | Create a note draft | admin |
|
|
| `notes.notes.update` | Update note title/body/status/tags | admin |
|
|
| `notes.relationships.link` | Create typed relationship between notes | admin |
|
|
| `notes.tasks.extract` | Extract tasks from note body | admin |
|
|
| `notes.artifacts.attach` | Attach artifact to a note | admin |
|
|
|
|
|
|
---
|
|
|
|
## Cross-Repo Automation
|
|
|
|
For periodic maintenance tasks that span all ByteLyst repos (test audits, coverage gaps, dependency checks, secret scans, typecheck sweeps), see the **Coding Agent Automation Playbook**:
|
|
|
|
> [`../learning_ai_common_plat/docs/devops/CODING_AGENT_AUTOMATION_PLAYBOOK.md`](../learning_ai_common_plat/docs/devops/CODING_AGENT_AUTOMATION_PLAYBOOK.md)
|
|
|
|
Key tasks: workspace hygiene sweep, cross-repo test suite, backend/web coverage gap analysis, TypeScript typecheck sweep, dependency health check, secret scan, code quality audit, AGENTS.md consistency check.
|