agentleFS
moodlehqmoodlehq/moodleapp/.github/copilot-instructions.md

moodleapp

Copilot instructions1k starsChanged 9 months agoApache-2.0View on GitHub

Import from @singletons for platform APIs, only import directly from @angular/core or Ionic when necessary. Main routing modules: - CoreMainMenuRoutingModule - Top-level tabs (calendar, messages, etc.) - CoreMainMenuTabRoutingModule - Child routes within tabs - CoreCourseContentsRoutingModule - Module used to register routes in the course contents page. These are routes that will only be used on single activity courses where the activity uses split-view navigation in tablets, such as forum or glossary. - CoreCourseIndexRoutingModule - Course tab pages - CoreMainMenuHomeRoutingModule -…

We split this copilot-instructions.md into the rules it gives an agent

14 rules. About 0 are common, 2 are distinctive, and 12 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 12

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Import from @singletons for platform APIs, only import directly from @angular/core or Ionic when necessary.

    line 15
  2. Distinctive:

    Use barrel exports for cleaner imports:

    line 33
  3. Very specific:

    Use buildTabMainRoutes() helper for consistent tab navigation

    line 59
  4. Very specific:

    Use CoreSyncCronHandler for background sync

    line 79
  5. Very specific:

    Before serving, Gulp tasks auto-run: lang, env, icons, optionally behat

    line 90
  6. Very specific:

    Test files: /*.test.ts with setup in src/testing/setup.ts

    line 99
  7. Very specific:

    Avoid creating separate -lazy.module.ts files.

    line 130
  8. Very specific:

    Always use singletons via @singletons instead of injecting Angular services directly

    line 157
  9. Very specific:

    Use standalone components for new modules instead of @NgModule({ declarations: [] })

    line 158
  10. Very specific:

    Always register handlers in provideAppInitializer

    line 159
  11. Very specific:

    Import only from barrel files that are configured in tsconfig.json paths

    line 160
  12. Very specific:

    Do run gulp before testing to ensure lang files are built

    line 161
  13. Very specific:

    Do use CoreSitesReadingStrategy when fetching data to control cache vs network behavior

    line 162
  14. Distinctive:

    When performing a code review, check that the language is in British English.

    line 166

≈ “Common” is an estimate: at least 1 in 5 of the 3,669 Copilot instructions files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
copilot-instructions.md

Moodle Mobile App - AI Agent Guidelines

Project Overview

This is the official Moodle Mobile App - an Ionic/Angular hybrid application that runs on Android and iOS via Cordova. The app provides offline-first access to Moodle LMS functionality.

Architecture Patterns

Singleton Services via makeSingleton

Services are NOT Angular-managed singletons. Use the makeSingleton pattern:

@Injectable({ providedIn: 'root' })
export class MyService { }
export const My = makeSingleton(MyService);

Import from @singletons for platform APIs, only import directly from @angular/core or Ionic when necessary.

Delegate Pattern for Extensibility

The codebase uses delegates extensively to allow addons to register handlers:

  • CoreDelegate base class in src/core/classes/delegate.ts
  • Handlers register in module providers using provideAppInitializer:
@NgModule({
    providers: [
        provideAppInitializer(() => {
            CoreCourseModuleDelegate.registerHandler(AddonModPageModuleHandler.instance);
        }),
    ],
})
  • Delegate examples: CoreCourseModuleDelegate, CoreContentLinksDelegate, CoreCourseModulePrefetchDelegate, CoreMainMenuDelegate

Path Aliases (TypeScript)

Use barrel exports for cleaner imports:

  • @/ - Project root
  • @singletons / @singletons/* - Core singletons
  • @services/* - Core services
  • @features/* - Core features
  • @components/*, @directives/*, @pipes/* - UI elements
  • @addons/* - Addon modules
  • @classes/* - Shared classes

Lazy Loading with Dynamic Routes

Routes use Angular's ROUTES injection token with factory functions:

@NgModule({
    providers: [
        { provide: ROUTES, multi: true, useFactory: buildRoutes, deps: [Injector] },
    ],
})
export default class MyLazyModule {}

Main routing modules:

  • CoreMainMenuRoutingModule - Top-level tabs (calendar, messages, etc.)
  • CoreMainMenuTabRoutingModule - Child routes within tabs
  • CoreCourseContentsRoutingModule - Module used to register routes in the course contents page. These are routes that will only be used on single activity courses where the activity uses split-view navigation in tablets, such as forum or glossary.
  • CoreCourseIndexRoutingModule - Course tab pages
  • CoreMainMenuHomeRoutingModule - Home page tabs
  • CoreSitePreferencesRoutingModule - Site preferences pages
  • Use buildTabMainRoutes() helper for consistent tab navigation

Cache Data Layer

SQLite Database: Site-specific tables via CORE_SITE_SCHEMAS token:

providers: [
    { provide: CORE_SITE_SCHEMAS, useValue: [MY_SCHEMA], multi: true }
]

File Management:

  • CoreFilepool - Downloads/caches files with queue management
  • CoreCourseModulePrefetchDelegate - Handles module prefetching for offline
  • CoreCourseHelper - Manages course and section downloads for offline access
  • CoreFileProvider - Manages file operations (read, write, delete) across device storage
  • Files stored in filepool with metadata tracking (stale detection, external file flags)

Sync Pattern:

  • Offline actions stored in local DB tables
  • Sync services (extend CoreSyncBaseProvider) process on connection
  • Use CoreSyncCronHandler for background sync

Development Workflows

Build & Serve

npm start              # Dev server with SSL at localhost:8100
npm run build          # Development build
npm run build:prod     # Production build
npm run build:test     # Testing build with NODE_ENV=testing

Before serving, Gulp tasks auto-run: lang, env, icons, optionally behat

Testing

Unit Tests (Jest):

npm test              # Run all tests
npm run test:watch    # Watch mode
npm run test:coverage # With coverage

Test files: **/*.test.ts with setup in src/testing/setup.ts

E2E Tests (Behat):

  • Feature files in src/**/tests/behat/*.feature
  • PHP-based Behat communicates with app via window.behat API
  • Build plugin: gulp behat (requires MOODLE_APP_BEHAT_PLUGIN_PATH or MOODLE_DOCKER_WWWROOT)
  • Behat runtime in src/testing/services/behat-runtime.ts

Mobile Development

npm run dev:android    # Run on Android with livereload
npm run dev:ios        # Run on iOS
npm run prod:android   # Production Android build
npm run prod:ios       # Production iOS build

Custom Cordova plugin in cordova-plugin-moodleapp/ with TypeScript source compiled to www/index.js

Language Files

Distributed lang files compiled into src/assets/lang/{lang}.json:

npm run lang:update-langpacks  # Pull from Moodle language packs
npm run lang:create-langindex  # Generate language index

Watch for changes: gulp watch

Project-Specific Conventions

Module Structure

  • Core modules: src/core/features/{feature}/
  • Addon modules: src/addons/{type}/{name}/
  • Each feature has {name}.module.ts (eager) and {name}-lazy.module.ts (lazy-loaded routes) when needed
  • Avoid creating separate -lazy.module.ts files; instead use loadComponent with dynamic imports for lazy loading
  • Services in services/, components in components/, pages in pages/

Handler Pattern

Handlers are singletons with .instance property added by makeSingleton:

@Injectable({ providedIn: 'root' })
export class MyHandler extends CoreContentLinksHandler {
    name = 'AddonMyHandler';
    // ...implementation
}
export const MyHandler = makeSingleton(MyHandler);

Shared Module Usage

Components import CoreSharedModule which re-exports:

  • CoreBaseModule (CommonModule, FormsModule, IonicModule, TranslateModule)
  • CoreComponentsModule, CoreDirectivesModule, CorePipesModule

Database Schema Versioning

Define tables with columns, indexes in site schemas. Version increments trigger migrations.

Environment Configuration

moodle.config.json (gitignored) extends moodle.config.example.json. Access via CoreConstants.CONFIG service. Test config overrides via TestingBehatRuntime.init().

Common Pitfalls

  1. Always use singletons via @singletons instead of injecting Angular services directly
  2. Use standalone components for new modules instead of @NgModule({ declarations: [] })
  3. Always register handlers in provideAppInitializer
  4. Import only from barrel files that are configured in tsconfig.json paths
  5. Do run gulp before testing to ensure lang files are built
  6. Do use CoreSitesReadingStrategy when fetching data to control cache vs network behavior

Code reviews

  • When performing a code review, check that the language is in British English.

Download now (ZIP)

Trending

Quiet this year.thin dataabout the whole repository

Dec 2025: 0 mentionsJan 2026: 0 mentionsFeb 2026: 0 mentionsMar 2026: 0 mentionsApr 2026: 0 mentionsMay 2026: 0 mentionsJun 2026: 0 mentionsJul 2026: 0 mentionsAug 2026: 0 mentionsSep 2026: 0 mentionsOct 2026: 0 mentionsNov 2026: 0 mentions
Dec 2025Jun 2026Nov 2026
Mentions a month of the moodlehq/moodleapp repository that our weekly crawl found: only 13 in all, so this is a hint, not a trend. There is no adoption data for this file yet.

Who's talking about moodlehq/moodleapp

The biggest 5 of 13 mentions linking to the repository that our crawl found. Each line is their own headline.

See all 13

Talked about on GitHub and Stack Overflow (13 times).

On GitHub · 10

5 more on GitHub

On Stack Overflow · 3

  • Where files are headingNew Copilot instructions files have more rules about branches and pull requests, and fewer about code style.

    Of the Copilot instructions files we read, the 2,297 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.