Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .vortex/docs/content/development/ai.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
sidebar_label: AI
sidebar_position: 7
---

# AI

**Vortex** provides built-in support for AI coding agents. The integration is
configured through structured markdown files that give agents the context they
need to work effectively within the project.

## How it works

The AI integration follows the same two-tier documentation pattern used
throughout **Vortex**:

- **What** applies to the project is defined in the `docs/` directory. The
agent reads all files in `docs/` to understand project-specific decisions
such as testing conventions, CI configuration, deployment rules, and
release processes.
- **How** to perform operations is sourced from the
https://www.vortextemplate.com/docs (this site). The
`AGENTS.md` file instructs agents to fetch operational guides from the
website and cache them locally in `.data/ai-artifacts/`.

This means AI agents receive the same layered guidance as human developers:
project-level decisions first, then Vortex-level procedures.

## Configuration files

### `AGENTS.md`

The [`AGENTS.md`](https://github.com/drevops/vortex/blob/main/AGENTS.md) file
in the project root is the primary configuration for AI coding agents. It is
an agent-agnostic file that any AI tool can use.

Key sections include:

- **Daily development tasks** — a reference of `ahoy` commands for building,
testing, and managing the local environment.
- **Critical rules** — constraints that agents must always follow (e.g., never
modify `scripts/vortex/`, always export config after admin UI changes).
- **Key directories** — the project's directory layout.
- **Documentation** — instructions for agents to check `docs/` files for
project-specific decisions and to fetch operational documentation from
https://www.vortextemplate.com/docs. Fetched documentation is cached locally so
that agents can reuse it across sessions without repeated requests.

### `CLAUDE.md`

The [`CLAUDE.md`](https://github.com/drevops/vortex/blob/main/CLAUDE.md) file
is automatically loaded by Claude Code at the start of every session. It
references `AGENTS.md` for the full development guide.
33 changes: 9 additions & 24 deletions .vortex/installer/src/Prompts/Handlers/AiCodeInstructions.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,29 @@

namespace DrevOps\VortexInstaller\Prompts\Handlers;

class AiCodeInstructions extends AbstractHandler {

const NONE = 'none';
use DrevOps\VortexInstaller\Utils\File;

const CLAUDE = 'claude';
class AiCodeInstructions extends AbstractHandler {

/**
* {@inheritdoc}
*/
public function label(): string {
return 'AI code assistant instructions';
return 'Provide AI agent instructions?';
}

/**
* {@inheritdoc}
*/
public function hint(array $responses): ?string {
return 'Provides AI coding assistants with better context about the project.';
}

/**
* {@inheritdoc}
*/
public function options(array $responses): ?array {
return [
self::CLAUDE => 'Anthropic Claude',
self::NONE => 'None',
];
return 'Provides AI coding agents with better context about the project.';
}

/**
* {@inheritdoc}
*/
public function default(array $responses): null|string|bool|array {
return self::CLAUDE;
return TRUE;
}

/**
Expand All @@ -49,21 +37,18 @@ public function discover(): null|string|bool|array {
return NULL;
}

if (is_readable($this->dstDir . '/CLAUDE.md')) {
return self::CLAUDE;
}

return self::NONE;
return File::exists($this->dstDir . '/AGENTS.md') || File::exists($this->dstDir . '/CLAUDE.md');
}

/**
* {@inheritdoc}
*/
public function process(): void {
$v = $this->getResponseAsString();
$v = $this->getResponseAsBool();
$t = $this->tmpDir;

if ($v !== self::CLAUDE) {
if (!$v) {
@unlink($t . '/AGENTS.md');
@unlink($t . '/CLAUDE.md');
Comment on lines 46 to 52
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle legacy string values before calling getResponseAsBool().
Line 47 will throw if a user still has legacy env/config values like "claude" or "none" set, which breaks non‑interactive installs. Add a compatibility path to coerce legacy strings to booleans before proceeding.

🩹 Suggested backward‑compatibility fix
-  public function process(): void {
-    $v = $this->getResponseAsBool();
+  public function process(): void {
+    try {
+      $v = $this->getResponseAsBool();
+    }
+    catch (\RuntimeException $e) {
+      // Backward compatibility for legacy string values (e.g. "claude"/"none").
+      $legacy = $this->getResponseAsString();
+      $v = !in_array(strtolower($legacy), ['none', 'false', '0', 'no'], true);
+    }
     $t = $this->tmpDir;
 
     if (!$v) {
       `@unlink`($t . '/AGENTS.md');
       `@unlink`($t . '/CLAUDE.md');
     }
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public function process(): void {
$v = $this->getResponseAsString();
$v = $this->getResponseAsBool();
$t = $this->tmpDir;
if ($v !== self::CLAUDE) {
if (!$v) {
@unlink($t . '/AGENTS.md');
@unlink($t . '/CLAUDE.md');
public function process(): void {
try {
$v = $this->getResponseAsBool();
}
catch (\RuntimeException $e) {
// Backward compatibility for legacy string values (e.g. "claude"/"none").
$legacy = $this->getResponseAsString();
$v = !in_array(strtolower($legacy), ['none', 'false', '0', 'no'], true);
}
$t = $this->tmpDir;
if (!$v) {
`@unlink`($t . '/AGENTS.md');
`@unlink`($t . '/CLAUDE.md');
🤖 Prompt for AI Agents
In @.vortex/installer/src/Prompts/Handlers/AiCodeInstructions.php around lines
46 - 52, The process() method calls getResponseAsBool() directly which will
throw for legacy string values like "claude" or "none"; before calling
getResponseAsBool() inspect the raw response (e.g. via getResponse() or the
underlying input), coerce legacy string values ("claude","none", etc.) into the
proper boolean value, then call getResponseAsBool(); update process() to use the
coerced value for $v and keep the existing cleanup of $this->tmpDir
.'/AGENTS.md' and '/CLAUDE.md' so non‑interactive installs handle legacy config
strings safely.

}
}
Expand Down
4 changes: 2 additions & 2 deletions .vortex/installer/src/Prompts/Handlers/Tools.php
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ public static function getToolDefinitions(string $filter = 'all'): array {
],
'strings' => ['/^.*phpunit.*\n?/m'],
'lines' => [
'CLAUDE.md' => [
'AGENTS.md' => [
'# PHPUnit testing',
'ahoy test # Run PHPUnit tests',
'ahoy test-unit',
Expand Down Expand Up @@ -334,7 +334,7 @@ public static function getToolDefinitions(string $filter = 'all'): array {
'/^.*\bgherkinlint\b.*\n?/m',
],
'lines' => [
'CLAUDE.md' => [
'AGENTS.md' => [
'# Behat testing',
'ahoy test-bdd',
],
Expand Down
4 changes: 2 additions & 2 deletions .vortex/installer/src/Prompts/PromptManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public function runPrompts(): void {
->add(fn($r, $pr, $n): bool => confirm(...$this->args(PreserveDocsProject::class)), PreserveDocsProject::id())

->intro('AI')
->add(fn($r, $pr, $n): int|string => select(...$this->args(AiCodeInstructions::class)), AiCodeInstructions::id());
->add(fn($r, $pr, $n): bool => confirm(...$this->args(AiCodeInstructions::class)), AiCodeInstructions::id());

// @formatter:on
// phpcs:enable Generic.Functions.FunctionCallArgumentSpacing.TooMuchSpaceAfterComma
Expand Down Expand Up @@ -468,7 +468,7 @@ public function getResponsesSummary(): array {
$values['Preserve project documentation'] = Converter::bool($responses[PreserveDocsProject::id()]);

$values['AI'] = Tui::LIST_SECTION_TITLE;
$values['AI code assistant instructions'] = $responses[AiCodeInstructions::id()];
$values['AI agent instructions'] = Converter::bool($responses[AiCodeInstructions::id()]);

$values['Locations'] = Tui::LIST_SECTION_TITLE;
$values['Current directory'] = $this->config->getRoot();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# star wars - Development Guide

## Daily Development Tasks

```bash
# Environment
ahoy up # Start containers
ahoy down # Stop containers
ahoy info # Show URLs and status
ahoy login # Get admin login URL

# Build & Database
ahoy download-db # Download fresh database from remote
ahoy build # Complete site rebuild
ahoy provision # Re-provision (import DB + apply config)
ahoy import-db # Import database from file without applying config
ahoy export-db # Export current local database

# Drush commands
ahoy drush cr # Clear cache
ahoy drush updb # Run database updates
ahoy drush cex # Export configuration to code
ahoy drush cim # Import configuration from code
ahoy drush uli # Get one-time login link
ahoy drush status # Check site status

# Composer
ahoy composer install
ahoy composer require drupal/[module_name]

# Code quality
ahoy lint # Check code style
ahoy lint-fix # Auto-fix code style

# PHPUnit testing
ahoy test # Run PHPUnit tests
ahoy test-unit # Run PHPUnit Unit tests
ahoy test-kernel # Run PHPUnit Kernel tests
ahoy test-functional # Run PHPUnit Functional tests
ahoy test -- --filter=TestClassName # Run specific PHPUnit test class

# Behat testing
ahoy test-bdd # Run Behat tests
ahoy test-bdd -- --tags=@tagname # Run Behat tests with specific tag
```

## Critical Rules

- **Never modify** `scripts/vortex/` - use `scripts/custom/` for your scripts
- **Never use** `ahoy drush php:eval` - use `ahoy drush php:script` instead
- **Always export config** after admin UI changes: `ahoy drush cex`

## Key Directories

- `web/modules/custom/` - Custom modules
- `web/themes/custom/` - Custom themes
- `config/default/` - Drupal configuration
- `scripts/custom/` - Project scripts
- `patches/` - Module patches

## Documentation

This project uses two documentation sources:

### Project-specific documentation (`docs/`)

The `docs/` directory contains **what** applies to this project:

- `docs/testing.md` - Testing conventions and agreements
- `docs/ci.md` - CI provider and configuration
- `docs/deployment.md` - Hosting provider and deployment rules
- `docs/releasing.md` - Version scheme and release process
- `docs/faqs.md` - Project-specific FAQs

**Always check these files first** to understand project-specific decisions.

### Vortex documentation (vortextemplate.com)

For **how** to perform operations, fetch from https://www.vortextemplate.com/docs.

Use the sitemap to discover available pages: https://www.vortextemplate.com/sitemap.xml

**Caching:** Save fetched docs to `.data/ai-artifacts/docs-[topic].md` with header
`<!-- Source: [URL] | Cached: [YYYY-MM-DD] -->`.
Re-fetch if user reports docs are outdated.
Original file line number Diff line number Diff line change
@@ -1,91 +1,3 @@
# star wars - Development Guide
# AI Agent Configuration

<!-- CLAUDE_CONTEXT
Drupal project built with Vortex template. Uses Docker locally, ahoy commands.
For detailed guides, fetch from https://www.vortextemplate.com and cache in .claude/artifacts/.
-->

## Daily Development Tasks

```bash
# Environment
ahoy up # Start containers
ahoy down # Stop containers
ahoy info # Show URLs and status
ahoy login # Get admin login URL

# Build & Database
ahoy download-db # Download fresh database from remote
ahoy build # Complete site rebuild
ahoy provision # Re-provision (import DB + apply config)
ahoy import-db # Import database from file without applying config
ahoy export-db # Export current local database

# Drush commands
ahoy drush cr # Clear cache
ahoy drush updb # Run database updates
ahoy drush cex # Export configuration to code
ahoy drush cim # Import configuration from code
ahoy drush uli # Get one-time login link
ahoy drush status # Check site status

# Composer
ahoy composer install
ahoy composer require drupal/[module_name]

# Code quality
ahoy lint # Check code style
ahoy lint-fix # Auto-fix code style

# PHPUnit testing
ahoy test # Run PHPUnit tests
ahoy test-unit # Run PHPUnit Unit tests
ahoy test-kernel # Run PHPUnit Kernel tests
ahoy test-functional # Run PHPUnit Functional tests
ahoy test -- --filter=TestClassName # Run specific PHPUnit test class

# Behat testing
ahoy test-bdd # Run Behat tests
ahoy test-bdd -- --tags=@tagname # Run Behat tests with specific tag
```

## Critical Rules

- **Never modify** `scripts/vortex/` - use `scripts/custom/` for your scripts
- **Never use** `ahoy drush php:eval` - use `ahoy drush php:script` instead
- **Always export config** after admin UI changes: `ahoy drush cex`

## Key Directories

- `web/modules/custom/` - Custom modules
- `web/themes/custom/` - Custom themes
- `config/default/` - Drupal configuration
- `scripts/custom/` - Project scripts
- `patches/` - Module patches

## Documentation

This project uses two documentation sources:

### Project-specific documentation (`docs/`)

The `docs/` directory contains **what** applies to this project:

- `docs/testing.md` - Testing conventions and agreements
- `docs/ci.md` - CI provider and configuration
- `docs/deployment.md` - Hosting provider and deployment rules
- `docs/releasing.md` - Version scheme and release process
- `docs/faqs.md` - Project-specific FAQs

**Always check these files first** to understand project-specific decisions.

### Vortex documentation (vortextemplate.com)

For **how** to perform operations, fetch from https://www.vortextemplate.com.

Use the sitemap to discover available pages:
https://www.vortextemplate.com/sitemap.xml

**Caching:** Save fetched docs to `.claude/artifacts/docs-[topic].md` with header
`<!-- Source: [URL] | Cached: [YYYY-MM-DD] -->`.
Re-fetch if user reports docs are outdated.
@AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@@ -57,8 +57,8 @@
@@ -52,8 +52,8 @@

## Key Directories

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@@ -57,8 +57,8 @@
@@ -52,8 +52,8 @@

## Key Directories

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@@ -1,4 +1,4 @@
-# star wars - Development Guide
+# New hope - Development Guide

## Daily Development Tasks

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@@ -37,16 +37,6 @@
@@ -32,16 +32,6 @@
ahoy lint # Check code style
ahoy lint-fix # Auto-fix code style

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@@ -37,16 +37,6 @@
@@ -32,16 +32,6 @@
ahoy lint # Check code style
ahoy lint-fix # Auto-fix code style

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@@ -44,9 +44,6 @@
@@ -39,9 +39,6 @@
ahoy test-functional # Run PHPUnit Functional tests
ahoy test -- --filter=TestClassName # Run specific PHPUnit test class

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@@ -44,9 +44,6 @@
@@ -39,9 +39,6 @@
ahoy test-functional # Run PHPUnit Functional tests
ahoy test -- --filter=TestClassName # Run specific PHPUnit test class

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@@ -37,13 +37,6 @@
@@ -32,13 +32,6 @@
ahoy lint # Check code style
ahoy lint-fix # Auto-fix code style

Expand Down
Loading