Problem/Motivation

We need to create some scaffolding to automatically alert agents as to the existence of these files.

Proposed resolution

Leverage the Drupal Composer Scaffold to move the Markdown files within this repository to where agents will load it automatically.

Remaining tasks

User interface changes

API changes

Data model changes

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

    Comments

    webchick created an issue. See original summary.

    webchick’s picture

    Issue summary: View changes
    webchick’s picture

    Assigned: Unassigned » marcus_johansson
    ronaldtebrake’s picture

    Version: » 1.0.x-dev

    For that I think we can use .agents/skills as the place to scaffold to, according to the spec at least 15 tools have already committed this directory to be the standard folder for agent skills to live: Proposal: include a standard folder where agent skills should be #15

    webchick’s picture

    Status: Active » Needs review

    There is some code to do scaffolding in there now (thank you!!). I have not yet tested it.

    phenaproxima’s picture

    I actually don't think you need to use scaffold files.

    If this project is going to be just a bunch of Markdown files, why not install it directly into .agents/skills/drupal or something like that?

    As long as the project's type key in composer.json is library (and it should be), then you could, to my knowledge, use composer/installers to place it:

    "extra": {
      "installer-paths": {
        ".agents/skills/drupal": ["drupal/ai_best_practices"]
      }
    }
    
    marcus_johansson’s picture

    Assigned: marcus_johansson » Unassigned

    I've created some base scaffolding and a base agents.md and a test skills.md. I also added some linked gemini and claude files and wrote a readme how to set it up in other coding tools. Its pushed directly at the repo, since we didn't have any start repo.

    tobiasb’s picture

    @phenaproxima

    This does not work. Composer packages with default type (library) can not move to another place than vendor, even with composer/installers not.

    Ref. https://github.com/composer/installers/issues/512

    We could create an issue, for a new composer type skill. :D

    webchick’s picture

    Status: Needs review » Needs work

    Confirmed that this doesn't seem to work as-is, at least with Claude Code.

    # note: without @dev at the end, I got an angry "could not find a version of package drupal/ai_best_practices matching your minimum-stability (stable)" error
    % composer require --dev drupal/ai_best_practices:@dev
    ./composer.json has been updated
    Running composer update drupal/ai_best_practices
    Loading composer repositories with package information
    Updating dependencies
    Lock file operations: 1 install, 0 updates, 0 removals
      - Locking drupal/ai_best_practices (1.0.x-dev 7b3110f)
    Writing lock file
    Installing dependencies from lock file (including require-dev)
    Package operations: 1 install, 0 updates, 0 removals
      - Downloading drupal/ai_best_practices (1.0.x-dev 7b3110f)
      - Installing drupal/ai_best_practices (1.0.x-dev 7b3110f): Extracting archive
    Package pear/console_getopt is abandoned, you should avoid using it. No replacement was suggested.
    Generating autoload files
    44 packages you are using are looking for funding.
    Use the `composer fund` command to find out more!
    Package drupal/ai_best_practices has scaffold operations, and is already allowed in the root-level composer.json file.
    Scaffolding files for drupal/ai_best_practices:
      - Copy [project-root]/AGENTS.md from agents/AGENTS.md
      - Copy [project-root]/CLAUDE.md from agents/CLAUDE.md
      - Copy [project-root]/GEMINI.md from agents/GEMINI.md
    No security vulnerability advisories found.
    

    And yet...

    % claude
    ▗ ▗   ▖ ▖  Claude Code v2.1.91
               Sonnet 4.6 · Claude Enterprise                                                                                                                                                                            
      ▘▘ ▝▝    ~/my-drupal-site
    
    ❯ /skills                                                                                                                                                                                                            
             
    ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
      Skills                                                                                                                                                                                                           
      No skills found                                                                                                                                                                                                    
                                                                                                                                                                                                                         
      Create skills in .claude/skills/ or ~/.claude/skills/
    
    
    webchick’s picture

    Status: Needs work » Fixed

    Oops, nevermind, my bad. :D

    Claude explained that these skills are more "guidance" vs. "commands" and as a result CLAUDE.md -> AGENTS.md will set up the mapping to be used when Claude thinks it needs it.

    That part (moving files around to root) seems to be working, despite what #8 says:

    % ls -al
    total 552
    drwxr-xr-x   14 webchick  staff     448 Apr  3 01:58 .
    drwxr-x---+ 124 webchick  staff    3968 Apr  3 02:13 ..
    drwxr-xr-x@  25 webchick  staff     800 Apr  3 01:48 .ddev
    -rw-------@   1 webchick  staff     357 Apr  3 01:51 .editorconfig
    -rw-------@   1 webchick  staff    4243 Apr  3 01:51 .gitattributes
    -rw-r--r--@   1 webchick  staff     683 Apr  3 01:58 AGENTS.md # here
    -rw-r--r--@   1 webchick  staff     201 Apr  3 01:58 CLAUDE.md # here
    -rw-------@   1 webchick  staff    3871 Apr  3 01:58 composer.json
    -rw-------@   1 webchick  staff  230705 Apr  3 01:58 composer.lock
    -rw-r--r--@   1 webchick  staff     196 Apr  3 01:58 GEMINI.md # also here
    -rw-------@   1 webchick  staff   18002 Apr  3 01:49 LICENSE.txt
    drwx------@   3 webchick  staff      96 Apr  3 01:51 recipes
    drwx------@  31 webchick  staff     992 Apr  3 01:58 vendor
    drwxr-xr-x@  19 webchick  staff     608 Apr  3 01:51 web
    

    I then asked how to test that this is working if /skills shows nothing, and it said:

     The simplest test: cd into your Drupal site, start a new Claude Code session, and ask something like:                                                                 
                                                                
      What guidance do you have for writing Drupal tests?    
    

    In doing that, it responded:

    Here's the guidance from your project's writing-automated-tests.md:                                                                                                   
                                
      Test type selection                                                                                                                                                   
                                                                                                                                                                            
      Default to Functional or Kernel — not Unit. Drupal code integrates services, hooks, and entities through a DI container, making integration tests far more valuable.  
                                                                                                                                                                            
      ┌──────────────────────┬───────────────────┬─────────────────────────────────────────────────────────────┐                                                            
      │         Type         │    Base class     │                          Use when                           │                                                          
      ├──────────────────────┼───────────────────┼─────────────────────────────────────────────────────────────┤
      │ Functional           │ BrowserTestBase   │ Best default. HTTP, forms, UI, complex deps                 │
      ├──────────────────────┼───────────────────┼─────────────────────────────────────────────────────────────┤
      │ Kernel               │ KernelTestBase    │ Services/APIs/hooks without UI; faster                      │                                                            
      ├──────────────────────┼───────────────────┼─────────────────────────────────────────────────────────────┤                                                            
      │ FunctionalJavascript │ WebDriverTestBase │ AJAX, modals, dynamic JS interactions                       │                                                            
      ├──────────────────────┼───────────────────┼─────────────────────────────────────────────────────────────┤                                                            
      │ Unit                 │ UnitTestCase      │ Only for pure functions with zero container deps (uncommon) │                                                          
      ├──────────────────────┼───────────────────┼─────────────────────────────────────────────────────────────┤                                                            
      │ Build                │ BuildTestBase     │ Composer/codebase layout (advanced, rare)                   │                                                          
      └──────────────────────┴───────────────────┴─────────────────────────────────────────────────────────────┘                                                            
                                                                                                                                                                          
      Common traps                                                                                                                                                          
       
      Kernel tests — no config or tables are auto-installed. You must explicitly call:                                                                                      
      $this->installEntitySchema('node');                                                                                                                                 
      $this->installConfig(['my_module']);                                                                                                                                  
      $this->installSchema('module', ['table']);                                                            
                                                                                                                                                                            
      FunctionalJavascript — never leave waitForElement unasserted:
      // Wrong — always passes even if element never appears                                                                                                                
      $this->assertSession()->waitForElement('css', '#page-title');                                                                                                       
                                                                                                                                                                            
      // Correct                                                                                                                                                            
      $this->assertNotEmpty(
        $this->assertSession()->waitForElement('css', '#page-title')                                                                                                        
      );                                                                                                                                                                  
        
      Dual-container trap — Functional tests run two separate PHP processes (PHPUnit + web server) sharing a DB. State set in test code is not visible to the web server
      process.                                                                                                                                                              
       
      Required conventions                                                                                                                                                  
                                                                                                                                                                          
      - Add #[RunTestsInSeparateProcesses] to Kernel/Functional/FunctionalJS classes (required in Drupal 11.3+, strongly recommended on 10.x)                               
      - Use correct namespaces: \Drupal\Tests\<module>\Functional, \Drupal\Tests\<module>\Kernel, etc. (FunctionalJavascript capitalization matters)
      - Run via DDEV with SIMPLETEST_BASE_URL and SIMPLETEST_DB set                                                                                                         
                                                                                                                                                                          
      When to write tests                                                                                                                                                   
                                                                                                                                                                          
      - Bug fixes: almost always need a test                                                                                                                                
      - Behaviour changes: almost always need a test                                                                                                                      
      - Config-only changes: usually do not
    
      Don't write Nightwatch tests — the community is moving to Playwright. 
    

    So I think this is working!! :D :D :D

    Now that this issue is closed, review the contribution record.

    As a contributor, attribute any organization that helped you, or if you volunteered your own time.

    Maintainers, credit people who helped resolve this issue.

    Status: Fixed » Closed (fixed)

    Automatically closed - issue fixed for 2 weeks with no activity.