From drupal-workflow
Generates and queries structural indexes for Drupal projects by parsing services.yml, routing.yml, hooks, plugins, and entity types. Builds dependency graphs for blast radius analysis, service mapping, and structural queries via /structural-index.
npx claudepluginhub gkastanis/drupal-workflow --plugin drupal-workflowThis skill uses the workspace's default tool permissions.
Automated structural awareness for Drupal projects — parses declarative configs to map services, routes, hooks, plugins, and entities.
scripts/check-staleness.shscripts/generate-all.shscripts/generate-base-fields.shscripts/generate-dependency-graph.shscripts/generate-entity-map.shscripts/generate-entity-schemas.shscripts/generate-feature-map.shscripts/generate-hook-registry.shscripts/generate-method-index.shscripts/generate-permission-registry.shscripts/generate-plugin-registry.shscripts/generate-route-map.shscripts/generate-service-graph.shBuilds federated index from child draft/ directories at monorepo root, aggregating service-level context into root knowledge without deep code analysis. Use after /draft:init on services.
Discovers Logic IDs and file paths from semantic docs/semantic/ for efficient codebase exploration. Use /discover FEATURE for lookups, keyword search, --prime for business index before Glob/Grep/Explore.
Generates YAML index files (.ai/index/) for design system codebases: component inventory, relationship graph, summary stats. Enables fast AI agent queries on components and dependencies.
Share bugs, ideas, or general feedback.
Automated structural awareness for Drupal projects — parses declarative configs to map services, routes, hooks, plugins, and entities.
Project-Agnostic: Works with any Drupal project.
Fills the gap between semantic docs and raw codebase (Glob/Grep):
Layer 3: Semantic docs (@semantic-architect generated, business "why")
Layer 2: Structural index (script-generated, Drupal-aware "what" + "how connected")
Layer 1: Raw codebase (Glob/Grep/Read)
Layer 3 is generated by the @semantic-architect agent via /drupal-semantic. It reads Layer 2 + source code to produce business index, tech specs, and business schemas.
Without structural index:
With structural index:
discover deps:FEATURE$SKILL_DIR/scripts/generate-all.sh [project-dir]
Generates:
docs/semantic/structural/services.md — Service IDs, classes, injected dependenciesdocs/semantic/structural/routes.md — Route names, paths, controllers, accessdocs/semantic/structural/hooks.md — Hook implementations (procedural + OOP)docs/semantic/structural/plugins.md — Block, FieldType, Action, QueueWorker pluginsdocs/semantic/structural/entities.md — Content and config entity types (with Fields column)docs/semantic/structural/schemas.md — Entity schema summary (fields, references, lists per bundle)docs/semantic/structural/base-fields.md — Base field registry (from PHP baseFieldDefinitions())docs/semantic/structural/permissions.md — Permission registry (from *.permissions.yml)docs/semantic/structural/methods.md — Method index (public methods in Service/Controller/Form)docs/semantic/schemas/*.json — Per-bundle JSON schemas with field types, labels, cardinality, target types/bundles, allowed valuesdocs/semantic/schemas/*.base-fields.json — Per-entity base field schemas with entity metadata, field types, settingsdocs/semantic/DEPENDENCY_GRAPH.md — Cross-reference dependency analysisdocs/semantic/FEATURE_MAP.md — Feature overview with structural counts$SKILL_DIR/scripts/check-staleness.sh [project-dir]
Reports which structural files need regeneration based on file modification times.
Once generated, query structural data through the discover skill:
discover service:entity_type.manager # Find a service
discover svc:config.factory # Shorthand
discover route:/admin/config # Find routes by path
discover path:/node # Shorthand
discover hook:node_presave # Find hook implementations
discover plugin:Block # Find block plugins
discover entity:node # Find entity types
discover schema:node # Show field schemas for node bundles
discover perm:administer # Find permissions
discover method:Timesheet # Find methods related to timesheets
discover deps:AUTH # Blast radius / dependency analysis
discover impact:my_module # What depends on this module
| Service ID | Class | Dependencies | Module | Tags |
|------------|-------|--------------|--------|------|
| my_module.service | Drupal\my_module\Service | @entity_type.manager, @config.factory | my_module | event_subscriber |
| Route Name | Path | Controller/Form | Access | Module |
|------------|------|-----------------|--------|--------|
| my_module.settings | /admin/config/my-module | MyController::settings | administer site | my_module |
| Hook Name | Implementation | Type | File | Module |
|-----------|---------------|------|------|--------|
| node_presave | my_module_node_presave | procedural | my_module.module | my_module |
| form_alter | MyHooks::formAlter | oop | src/Hook/MyHooks.php | my_module |
| Plugin Type | ID | Class | Module | File |
|-------------|----|-------|--------|------|
| Block | my_custom_block | MyCustomBlock | my_module | src/Plugin/Block/MyCustomBlock.php |
| Entity Type | ID | Class | Handlers | Fields | Module | File |
|-------------|----|-------|----------|--------|--------|------|
| ContentEntityType | node | Node | list_builder, form, views_data | 12 (5 ref, 2 list) | node | core/modules/node/src/Entity/Node.php |
| Entity Type | Bundle | Fields | References | Lists | Schema File |
|-------------|--------|--------|------------|-------|-------------|
| node | article | 5 | 2 | 1 | schemas/node.article.json |
| Entity Type | Kind | Base Fields | References | Lists | Computed | Schema File |
|-------------|------|-------------|------------|-------|----------|-------------|
| timan_assignment | Content | 19 | 3 | 3 | 1 | schemas/timan_assignment.base-fields.json |
| Permission | Title | Module | Restricted | Description |
|------------|-------|--------|------------|-------------|
| administer timan holidays | Administer holidays | timan_holiday | yes | Create, edit, and delete public holidays. |
| Service Class | Method | Return Type | Module | File | Line |
|---------------|--------|-------------|--------|------|------|
| HolidayService | getHolidaysInRange() | array | timan_holiday | www/.../HolidayService.php | 45 |
discover schema:ENTITY){
"entity_type": "timan_assignment",
"entity_kind": "Content",
"base_table": "timan_assignment",
"entity_keys": {"id": "id", "uuid": "uuid", "label": "label", "owner": "uid"},
"admin_permission": "administer timan assignments",
"has_owner": true,
"base_fields": {
"label": {"type": "string", "label": "Label", "required": true, "cardinality": 1, "settings": {"max_length": 255}}
},
"field_count": 19,
"ref_count": 3,
"list_count": 3,
"computed_count": 1
}
discover schema:ENTITY){
"entity_type": "node",
"bundle": "article",
"fields": {
"field_tags": {
"type": "entity_reference",
"label": "Tags",
"required": false,
"cardinality": -1,
"target_type": "taxonomy_term",
"target_bundles": ["tags"]
}
},
"field_count": 5,
"ref_count": 2,
"list_count": 1
}
Known limitations (config schemas):
*.base-fields.json files.config/sync, config/default, config/staging, ../config/sync). Projects with non-standard paths need to symlink or adjust.Known limitations (base fields):
parent::baseFieldDefinitions() (id, uuid, langcode) are implicit — not enumerated.baseFieldDefinitions() are skipped.permission_callbacks are not detected.Compact overview (~500 tokens) always loaded during session priming:
| Code | Name | Services | Hooks | Routes | Plugins | Entities | Hotspots | Spec |
Sections:
docs/semantic/ directory (for output location)yq for improved YAML parsing accuracy