Imported from open-learning-exchange/planet (
AGENTS.md). Install upstream withnpx skills add open-learning-exchange/planet. Copyright stays with the author.
AGENTS.md
This file provides shared guidance for AI coding agents working in this repository. CLAUDE.md is a symlink to this file.
Commands
Prerequisites: Node.js v22, npm v10, Angular CLI v20. A CouchDB instance must be running (the README describes a Docker Compose setup that exposes CouchDB on port 2200 and chatapi/gateway on port 5000).
Angular app (root)
npm install— install dependencies.npm run install-hooks— copygit-hooks/*into.git/hooks. Thepre-pushhook runsnpm run lintin both the root andgateway/.npm start/ng serve— dev server on port 3000 (host0.0.0.0). If 3000 is taken, useng serve --port 3001.npm run dev— runsscripts/dev-env.sh(which templatessrc/environments/environment.dev.tsfromenvironment.templateusingCHAT_PORT,COUCH_PORT,PARENT_PROTOCOLfrom an optional.env) thenng serve --configuration dev. Use this when chatapi or CouchDB are on non-default ports.npm run build— production build viang-high-memory(--max_old_space_size=4096); large builds OOM without it.npm run test— Karma + Jasmine; openslocalhost:9876. There is noe2eworkflow wired up on this branch.- Single spec:
ng test --include src/app/path/to/file.spec.ts(or temporarily usefdescribe/fit). npm run lint— ESLint oversrc/**/*.{ts,html}via@angular-eslint/builder.ng lint --fixauto-fixes.npm run lint-all— sass-lint +ng lint --type-check+ htmlhint. Heavier than the pre-push hook.- Locales (en, so, fr, ne, ar, es):
ng serve --configuration <spa|fra|nep|ara|som>orLNG=es npm start. Locale configs, base hrefs, and xlf sources are defined inangular.jsonunderprojects.planet-app.i18n.
gateway (gateway/)
Independent Node service; requires its own .env (see gateway/README.md) with SERVE_PORT, COUCHDB_HOST, COUCHDB_USER, COUCHDB_PASS. macOS/Windows users typically use SERVE_PORT=5400 and mirror it in the root .env as CHAT_PORT.
cd gateway && npm install && npm run dev— nodemon + ts-node.npm run build—tsc.npm run lint/npm run lint-fix— uses legacy ESLint config (ESLINT_USE_FLAT_CONFIG=false); the root app uses flat config (eslint.config.mjs), so don't try to unify them casually.- Only one
gatewayinstance can bind the port at a time; stop the Docker gateway container beforenpm run dev.
CouchDB bootstrap
bash couchdb-setup.sh -p <port> creates databases and uploads design docs from design/. Re-run with -u <admin> -w <password> if auth breaks. The design/ tree holds CouchDB map/reduce views per database; design/create-design-docs.js walks subdirectories to assemble design documents that the setup script uploads.
Architecture
Planet Learning is an Angular 20 + CouchDB learning platform. There are two tiers of deployment — a Nation (cloud aggregator) server and a Community (local LAN) server — and most "sync" / "parent" / "manager" concepts in the code exist to bridge the two. environment.ts captures this: couchAddress is the local DB, parentProtocol + centerAddress point at the upstream Nation, and chatAddress points at the local gateway chat namespace.
Repository layout
src/app/— feature-per-directory Angular app. Each feature owns its own*-router.module.tsand is lazy-loaded fromsrc/app/app-router.module.ts, which mountsHomeModuleat''(guarded byUserGuard+UnsavedChangesGuard) andLoginModuleat/login(guarded byAuthService). Unknown routes fall through toPageNotFoundComponent.src/app/shared/— cross-feature services, directives, dialogs, and the database layer. Two DB abstractions live here:couchdb.service.ts— HTTP wrapper around CouchDB used by most features. Every request goes throughsetOpts/couchDBReq, which injectswithCredentialsand surfaces 403s viaPlanetMessageService. Prefer adding new calls through this service rather than rawHttpClient.database/pouch.service.ts+pouch-auth.service.ts— PouchDB mirror for offline-capable data (no databases are currently registered for mirroring). When adding an offline-capable database, register it in thedatabasesSet soconfigureDBs()creates the local mirror.
src/app/manager-dashboard/— admin surfaces (sync, fetch, AI configuration, reports, requests, certifications). AI provider keys/models are read from the CouchDBconfigurationsdatabase; do not hardcode them.gateway/— standalone Express + WebSocket gateway with internalchatapiandpublicmodules. It serves chat on the existing/ml/namespace and scoped public operations on/api/. Credentials/models come from the CouchDBconfigurationsdoc, not env vars.design/— CouchDB design documents (map/reduce views). Edit the per-db.jsfiles and re-runcouchdb-setup.shto upload.docker/— Dockerfiles forplanet(nginx + built Angular bundle),gateway, anddb-init.docker/planet/default.conf.templateanddocker/planet/scripts/drive the production entrypoint.scripts/— npm-invoked project maintenance helpers, including local dev environment templating and i18n catalog normalization.src/environments/—environment.ts(local dev),environment.dev.ts(generated byscripts/dev-env.sh, git-ignored),environment.test.ts,environment.prod.ts, plus theenvironment.templateconsumed byscripts/dev-env.sh.src/i18n/messages.*.xlf— translation catalogs; do not edit by hand outside a normal i18n workflow. Usenpm run i18n:extractto update the source catalog and normalize location metadata. Usenpm run i18n:normalizeto remove source file and line number metadata from existing catalogs. Usenpm run i18n:checkto validate extraction without changing committed files. Catalogs use Angular's current decimal message IDs.
Conventions worth internalizing before editing
From Style-Guide.md (read it before making UI changes):
- Keep component
template+styleinline when total HTML + CSS is <12 lines; otherwise split into.component.html/.component.scss. File naming is<feature><-sub-feature?>.<type>.ts; class names are CamelCase of the same. - Do not name variables
planet-db-hostorplanet-db-port— the production Docker entrypoint reserves those. - Use
i18non elements with real text; never on elements whose only content is interpolation. Attribute strings usei18n-<attr>(e.g.i18n-title). - Test-only CSS hooks use the
km-prefix and must never appear in stylesheets. Unit tests query elements via these classes. - All colors/breakpoints go through
src/app/_variables.scssand the Material theme (mat-color(),$primary/$accent/$warn); shared breakpoint overrides use thescreen-sizesmixin from_mixins.scss. - Validators live in
src/app/validators/(custom-validators.tsfor sync,validator.service.tsfor async); prefer those over inlining new validation logic. - Loading UX: page-level uses
*ngIf="isLoading"with a "Loading …" i18n string; action-level usesDialogsLoadingService.start()/.stop()inside an RxJSfinalize.
Git workflow
Develop on feature branches off master; the project asks for two positive reviews before merging. Install hooks (npm run install-hooks) so pre-push enforces lint in both ./ and gateway/.
PR titles follow the house style scope: smoother thing doing (fixes #N) (see the log; the merge-prepping skill below automates this). (fixes #N) goes in the title — the squash commit message is the PR title, so that's what auto-closes the issue on merge.
The Agent Spellbook
docs/AGENT_SPELLBOOK.md is the reference for working with the other AI agents on PRs (coderabbitai, codex, copilot, devin, openhands, the jules label, dependabot): the Grid of who answers how, the Laws of Summoning — read them before mentioning any agent handle — and "The Skill Sync", which covers how the shared agent skills under .agents/skills/ are wired up and maintained. Skill repos are git submodules, not initialized on a default clone or actions/checkout — run git submodule update --init --recursive before reading anything under .agents/skills/. Current skills: merge-prepping (PR titles into the house style above; source: https://github.com/dogi/merge-prepping), a submodule under .agents/skills/; and branch-overtaking (taking over an existing branch and its PR; source: https://github.com/dogi/branch-overtaking), registered for Claude Code only in .claude/settings.json with no submodule, so nothing under .agents/skills/ carries it.