Compare commits

..

13 Commits

Author SHA1 Message Date
marcus c47b83a75e docs: generalize health dashboard runbook paths 2026-05-11 14:36:16 +01:00
marcus 796d4ae381 docs: clarify health dashboard remediation (#35) 2026-05-10 08:57:31 +01:00
marcus 5d3ec80907 Resolve supervisor dashboard freshness alert (#32) (#33)
* wip: preserve worker changes on abnormal exit

* docs: document health dashboard remediation

* chore: drop restored metadata marker
2026-05-10 01:43:21 +01:00
marcus 4ecccbc107 fix: give Composer autoloader precedence and optimise PSR-4 loader (#30)
- Swap load_dependencies() before register_autoloader() in the
  constructor so Composer (when a vendor/ install is present) is
  registered on the spl_autoload stack first and therefore acts as
  the primary class resolver, with the custom loader as fallback.
- Add early-exit guard in the autoloader closure: skip the namespace
  map loop entirely for classes that don't share the plugin base
  prefix, avoiding unnecessary iteration on every WordPress class
  lookup.
- Store the namespace map in a static variable so it is allocated
  only once across all invocations rather than on each call.
- Switch from require_once to require inside the autoloader: the
  autoloader is only invoked for classes not yet defined, making the
  redundancy check in require_once unnecessary overhead.

Resolves #29
2026-04-26 11:01:53 +01:00
marcus 85d55e80fc feat: implement PSR-4 autoloader, remove manual require_once calls (#27)
- Add spl_autoload_register in Plugin::register_autoloader() mapping
  WPALLSTARS\FixPluginDoesNotExistNotices\Admin\ to admin/lib/ and
  WPALLSTARS\FixPluginDoesNotExistNotices\ to includes/
- Remove manual require_once calls for Core, Admin, and Modal classes
- Rename admin/lib/admin.php -> Admin.php and modal.php -> Modal.php
  for PSR-4 filename convention (class name must match file name)
- Fix composer.json: correct namespace case (WPAllStars -> WPALLSTARS)
  and add admin/lib/ directory mapping for Admin sub-namespace
- Fix wp-fix-plugin-does-not-exist-notices.php require_once to use
  correct case (plugin.php -> Plugin.php)

Resolves #25
2026-04-24 08:34:47 +01:00
marcus 5a80351d1f fix: correct class name and version locations in AGENTS.md
Resolves #24

- Use fully qualified class name WPALLSTARS\FixPluginDoesNotExistNotices\Plugin in version management snippet
- Replace misleading includes/Plugin.php entry (no version constant) with AGENTS.md as the fourth version location
- Add note clarifying Plugin.php passes version via constructor
- Add step 4 to bump-version checklist to update AGENTS.md version string
2026-04-24 08:28:14 +01:00
marcus 34b0b6f0d6 fix: replace ambiguous X.Y.Z placeholder with actual version in AGENTS.md (#23)
Gemini review (PR #14) flagged that 'X.Y.Z' in the Version Management
section is problematic for AI agents — they may interpret it literally
or fail to match it during automated edits.

Replace with the actual current version '2.4.0' plus a parenthetical
instruction '(replace 2.4.0 with the new version)' so the context is
unambiguous: agents can grep for the exact string and know what to
substitute.

Resolves #19
2026-04-23 05:29:11 +01:00
marcus 1d1380275e fix: add missing Updater.php require in load_dependencies and fix Core.php case (#22)
Resolves #20

- Adds require_once for includes/Updater.php which was instantiated in
  init_components() but never loaded in load_dependencies()
- Fixes includes/core.php → includes/Core.php case mismatch (would fail
  on case-sensitive Linux filesystems)
2026-04-23 05:26:36 +01:00
marcus b0bb363f99 fix: correct AI workflow doc file references to prevent read:file_not_found errors
fix: correct AI workflow doc file references to prevent read:file_not_found errors
2026-04-22 21:14:11 +01:00
marcus 17de1949ae fix: correct AI workflow doc file references to prevent read:file_not_found errors
- folder-structure.md: fix includes/core.php → Core.php, plugin.php → Plugin.php,
  updater.php → Updater.php (PascalCase matches actual filenames on disk)
- bug-fixing.md: fix fix-plugin-does-not-exist-notices.php →
  wp-fix-plugin-does-not-exist-notices.php (correct wp- prefix) and
  languages/fix-plugin... → languages/wp-fix-plugin... (same prefix fix)
- feature-development.md: remove reference to non-existent reference-plugins/
  directory to stop read:file_not_found errors when AI follows the docs

Addresses contributor insight issue #16: incorrect file paths in AI workflow
docs were the root cause of 23x read:file_not_found, 71x edit:not_read_first,
32x edit:edit_stale_read, and 66x bash:other errors in AI assistant sessions.
2026-04-22 21:09:42 +01:00
marcus 18cf60c2a4 fix: correct case-sensitive require_once paths and add AGENTS.md (#14)
* fix: correct case-sensitive require_once paths and add AGENTS.md for AI guidance

- Fix includes/plugin.php -> includes/Plugin.php in main plugin file
- Fix includes/core.php -> includes/Core.php in includes/Plugin.php
  (Linux case-sensitive filesystems fail silently on macOS; runtime bug on production)
- Fix .ai-workflows/folder-structure.md: update class files to PascalCase,
  remove references to non-existent admin/ subdirectories (images/, partials/,
  settings/, tools/) that caused read:file_not_found errors in AI sessions
- Add AGENTS.md with authoritative file map to reduce AI agent errors:
  edit:not_read_first, bash:other, edit:edit_stale_read, read:file_not_found

Resolves #13

* fix: markdown formatting in AGENTS.md (Codacy MD022/MD032)
2026-04-22 09:57:41 +01:00
marcus 3eaf8ec7a5 chore: add ai-training=false to .gitattributes 2026-03-26 01:32:25 +00:00
marcus ff838ec5f2 chore: fix malformed .gitignore entry and add loop-state ignore 2026-03-16 16:18:40 +00:00
13 changed files with 232 additions and 24 deletions
+2 -2
View File
@@ -144,12 +144,12 @@ Apply the minimal fix necessary to address the critical issue.
Increment the PATCH version and update all version numbers:
- Main plugin file (fix-plugin-does-not-exist-notices.php)
- Main plugin file (wp-fix-plugin-does-not-exist-notices.php)
- FPDEN_VERSION constant
- CHANGELOG.md
- readme.txt
- README.md
- languages/fix-plugin-does-not-exist-notices.pot (Project-Id-Version)
- languages/wp-fix-plugin-does-not-exist-notices.pot (Project-Id-Version)
### 4. Commit and Push
-1
View File
@@ -27,7 +27,6 @@ When implementing a new feature:
- Add appropriate comments
- Consider performance implications
- Maintain backward compatibility
- Review reference plugins in the `reference-plugins/` directory for inspiration and best practices
### 3. Update Documentation
+8 -11
View File
@@ -16,10 +16,6 @@ This document outlines the folder structure of the plugin and explains the purpo
- **admin/css/** - Admin-specific CSS files
- **admin/js/** - Admin-specific JavaScript files
- **admin/images/** - Admin-specific images
- **admin/partials/** - Admin-specific template partials
- **admin/settings/** - Admin settings functionality
- **admin/tools/** - Admin tools functionality
- **admin/lib/** - Admin-specific library files and helper functions
- **admin/lib/admin.php** - Admin class for handling admin-specific functionality
- **admin/lib/modal.php** - Modal class for handling the update source selector modal
@@ -28,13 +24,14 @@ This document outlines the folder structure of the plugin and explains the purpo
The `includes/` directory contains the core plugin functionality:
- **includes/core.php** - Core class for handling the main plugin functionality
- **includes/plugin.php** - Main plugin class that initializes all components
- **includes/updater.php** - Updater class for handling plugin updates
- **includes/Core.php** - Core class for handling the main plugin functionality
- **includes/Plugin.php** - Main plugin class that initializes all components
- **includes/Updater.php** - Updater class for handling plugin updates
## File Naming Conventions
- All PHP files in the `includes/` directory use lowercase filenames
- PHP class files in the `includes/` directory use PascalCase filenames matching the class name (e.g., `Core.php`, `Plugin.php`, `Updater.php`)
- PHP files in `admin/lib/` use lowercase filenames (e.g., `admin.php`, `modal.php`)
- All directories use lowercase names
- JavaScript and CSS files use kebab-case (e.g., `update-source-selector.js`)
@@ -50,10 +47,10 @@ The `includes/` directory contains the core plugin functionality:
When referring to files or directories in AI conversations, use the following format:
- **@includes/plugin.php** - Main plugin class
- **@includes/core.php** - Core functionality
- **@includes/Plugin.php** - Main plugin class
- **@includes/Core.php** - Core functionality
- **@admin/lib/admin.php** - Admin functionality
- **@admin/lib/modal.php** - Modal functionality
- **@includes/updater.php** - Updater functionality
- **@includes/Updater.php** - Updater functionality
- **@admin/js/update-source-selector.js** - Update source selector JavaScript
- **@admin/css/update-source-selector.css** - Update source selector CSS
@@ -0,0 +1,48 @@
# Supervisor health dashboard remediation
Use this runbook when the repository supervisor health dashboard becomes stale.
## Signals
- The pinned supervisor issue has an old `last_refresh:` marker.
- The stats scheduler exists and is loaded, but wrapper runs overlap or remain
active beyond the expected timeout.
- Recent stats logs stop before the affected repository is updated.
## Remediation
1. Confirm the scheduler and stats log are present:
```bash
launchctl list | grep -i aidevops-stats-wrapper
ls -la ~/Library/LaunchAgents/com.aidevops.aidevops-stats-wrapper.plist
tail -40 ~/.aidevops/logs/stats.log
```
2. Check for an active `stats-wrapper.sh` process that has exceeded `STATS_TIMEOUT`.
The default timeout is `600` seconds and is defined near the top of
`~/.aidevops/agents/scripts/stats-wrapper.sh`; an operator can confirm the
runtime value with a dry run:
```bash
STATS_DRY_RUN=1 bash ~/.aidevops/agents/scripts/stats-wrapper.sh --dry-run
```
3. Terminate the stale wrapper process and remove the stale stats pidfile at
`~/.aidevops/logs/stats.pid`.
4. Run one targeted health issue refresh for this repository:
```bash
REPO_SLUG="<owner/repo>" \
REPO_PATH="<your/local/path>" \
bash -lc '
source "$HOME/.aidevops/agents/scripts/shared-constants.sh"
source "$HOME/.aidevops/agents/scripts/worker-lifecycle-common.sh"
source "$HOME/.aidevops/agents/scripts/stats-functions.sh"
_update_health_issue_for_repo "$REPO_SLUG" "$REPO_PATH" "" "" ""
'
```
5. Verify the pinned dashboard issue now has a fresh `last_refresh:` marker and
recent `updated_at` timestamp.
+1
View File
@@ -10,6 +10,7 @@ This directory contains workflow documentation for AI assistants working with th
- **feature-development.md**: Process for developing new features
- **folder-structure.md**: Documentation of the plugin's folder structure and naming conventions
- **git-workflow.md**: Detailed git workflow and branch management guidelines
- **health-dashboard-remediation.md**: Supervisor health dashboard staleness triage and remediation
- **incremental-development.md**: Time-efficient approach for incremental development and testing
- **local-env-vars.md**: Local development environment paths and URLs
- **multi-repo-workspace.md**: Guidelines for working in workspaces with multiple repositories
+4 -1
View File
@@ -98,4 +98,7 @@ reference-plugins export-ignore
# Merge driver for changelog files to prevent conflicts
CHANGELOG.md merge=union
readme.txt merge=union
readme.txt merge=union
# Opt out of AI model training
* ai-training=false
+2 -1
View File
@@ -169,4 +169,5 @@ codecov.yml
webpack.config.js
gulpfile.js
Gruntfile.js
*.zip
*.zip
.agents/loop-state/
+104
View File
@@ -0,0 +1,104 @@
# AGENTS.md — AI Agent Guide for wp-fix-plugin-does-not-exist-notices
This file provides precise, verified guidance for AI agents working in this repository. Read it before editing any file to avoid `read:file_not_found` and `edit:not_read_first` errors.
## Repository Purpose
**Fix 'Plugin file does not exist' Notices** — a WordPress plugin that detects active plugins whose files are missing, adds them to the Plugins list with a "Remove Notice" action link, and safely removes their database references.
- GitHub: `wpallstars/wp-fix-plugin-does-not-exist-notices`
- Namespace: `WPALLSTARS\FixPluginDoesNotExistNotices`
- Text domain: `wp-fix-plugin-does-not-exist-notices`
- Current version: see `wp-fix-plugin-does-not-exist-notices.php` header
## Exact File Map (authoritative — verified against git ls-files)
**CRITICAL**: PHP class files in `includes/` use PascalCase. The docs and `require_once` paths must match exactly. On Linux (case-sensitive), wrong case = fatal error.
```
wp-fix-plugin-does-not-exist-notices.php # Plugin entry point — sets Version, requires includes/Plugin.php
includes/Plugin.php # Main Plugin class — loads dependencies, inits components
includes/Core.php # Core class — all WordPress hooks and plugin logic
includes/Updater.php # Updater class — handles Git Updater / WP.org update sources
admin/lib/admin.php # Admin\Admin class — admin page rendering, enqueues
admin/lib/modal.php # Admin\Modal class — update source selector modal
admin/css/admin-styles.css # General admin styles
admin/css/update-source-selector.css # Styles for the update source modal
admin/js/admin-scripts.js # General admin JS
admin/js/update-source-selector.js # JS for the update source modal
languages/wp-fix-plugin-does-not-exist-notices.pot # Translation template
build.sh # Build/release script
scripts/deploy-local.sh # Local deployment helper
composer.json # Composer config (no vendor/ committed)
README.md # Developer readme
readme.txt # WordPress.org readme (keep in sync with README.md)
CHANGELOG.md # Changelog (keep in sync with README.md and readme.txt)
```
**Directories that DO NOT exist** (do not attempt to read or create files here):
- `admin/images/` — does not exist
- `admin/partials/` — does not exist
- `admin/settings/` — does not exist
- `admin/tools/` — does not exist
- `vendor/` — not committed; loaded at runtime if present
## Before Editing Any File
1. Read the file first: `Read includes/Core.php` — not `includes/core.php` (wrong case fails).
2. Re-read the file if another tool call may have modified it since your last read.
3. Verify the file path with `git ls-files '<pattern>'` when uncertain.
## Version Management
Version appears in **four places** — all must be updated together:
1. `wp-fix-plugin-does-not-exist-notices.php``Version:` header and `new WPALLSTARS\FixPluginDoesNotExistNotices\Plugin(__FILE__, '2.4.0')` (replace `2.4.0` with the new version)
2. `readme.txt``Stable tag:` and changelog section
3. `CHANGELOG.md` — top entry
4. `AGENTS.md` — this file, item 1 above (replace the hardcoded version string)
Note: `includes/Plugin.php` has no direct version constant; the version is passed in via the constructor call in the entry point file.
`README.md` changelog section must also stay in sync with `CHANGELOG.md`.
## Common Tasks
### Fix a bug in core plugin logic
Edit `includes/Core.php`. All WordPress hooks are registered in the constructor.
### Change admin UI or settings
Edit `admin/lib/admin.php` (Admin class) and/or `admin/lib/modal.php` (Modal class).
CSS: `admin/css/admin-styles.css` or `admin/css/update-source-selector.css`.
JS: `admin/js/admin-scripts.js` or `admin/js/update-source-selector.js`.
### Bump version for a release
1. Update version in `wp-fix-plugin-does-not-exist-notices.php` (both header and constructor call).
2. Update `Stable tag:` in `readme.txt`.
3. Add changelog entry to `readme.txt`, `CHANGELOG.md`, and `README.md`.
4. Update the version string in `AGENTS.md` (item 1 of the Version Management list above).
### Add or fix update source logic
Edit `includes/Updater.php`.
## Git Workflow
- Branch naming: `feature/`, `fix/`, `patch/`, `refactor/` prefixes
- One branch per issue; one PR per issue
- Push to both `github` and `gitea` remotes
- Do not include version numbers in branch names during development
## AI Workflow Documentation
Extended guidance is in `.ai-workflows/`:
- `folder-structure.md` — directory layout with correct filenames
- `git-workflow.md` — branching, commit messages, remote management
- `feature-development.md` — feature development process
- `bug-fixing.md` — bug investigation and fix process
- `release-process.md` — full release checklist including Git Updater notes
- `dev-prefs-memory.md` — persistent developer preferences
+2 -1
View File
@@ -15,7 +15,8 @@
},
"autoload": {
"psr-4": {
"WPAllStars\\FixPluginDoesNotExistNotices\\": "includes/"
"WPALLSTARS\\FixPluginDoesNotExistNotices\\Admin\\": "admin/lib/",
"WPALLSTARS\\FixPluginDoesNotExistNotices\\": "includes/"
}
}
}
+60 -6
View File
@@ -77,6 +77,7 @@ class Plugin {
$this->define_constants();
$this->load_dependencies();
$this->register_autoloader();
$this->init_components();
}
@@ -97,22 +98,75 @@ class Plugin {
}
}
/**
* Register the PSR-4 autoloader
*
* Maps plugin namespaces to their corresponding directories so that
* new class files are loaded automatically without manual require_once calls.
*
* Optimisations applied:
* - Early exit when the class does not belong to this plugin's namespace,
* avoiding the loop entirely for every foreign class lookup.
* - The namespace map is stored in a static variable so it is allocated
* only once across all invocations rather than on every class lookup.
* - `require` is used instead of `require_once` because the autoloader is
* only called for classes that are not yet defined, making the redundancy
* check in `require_once` unnecessary.
*
* @return void
*/
private function register_autoloader() {
$plugin_dir = $this->plugin_dir;
spl_autoload_register(function ($class) use ($plugin_dir) {
// Skip immediately if the class is not in this plugin's namespace.
$base_prefix = 'WPALLSTARS\\FixPluginDoesNotExistNotices\\';
if (strncmp($base_prefix, $class, strlen($base_prefix)) !== 0) {
return;
}
// Static map allocated once; ordered most-specific first so Admin\
// resolves before the root namespace.
static $namespace_map = null;
if ($namespace_map === null) {
$namespace_map = array(
'WPALLSTARS\\FixPluginDoesNotExistNotices\\Admin\\' => 'admin/lib/',
'WPALLSTARS\\FixPluginDoesNotExistNotices\\' => 'includes/',
);
}
foreach ($namespace_map as $prefix => $relative_path) {
if (strncmp($prefix, $class, strlen($prefix)) !== 0) {
continue;
}
$relative_class = substr($class, strlen($prefix));
$file = $plugin_dir . $relative_path . str_replace('\\', DIRECTORY_SEPARATOR, $relative_class) . '.php';
if (file_exists($file)) {
require $file;
return;
}
}
});
}
/**
* Load dependencies
*
* Loads the Composer autoloader when available (vendor installs), registering
* it on the spl_autoload stack before the custom PSR-4 loader so that Composer
* acts as the primary resolver. Project classes without a vendor install are
* resolved by the autoloader registered in register_autoloader().
*
* @return void
*/
private function load_dependencies() {
// Load composer autoloader if it exists
// Load composer autoloader if it exists (vendor/ directory present).
$autoloader = $this->plugin_dir . 'vendor/autoload.php';
if (file_exists($autoloader)) {
require_once $autoloader;
}
// Load required files
require_once $this->plugin_dir . 'includes/core.php';
require_once $this->plugin_dir . 'admin/lib/admin.php';
require_once $this->plugin_dir . 'admin/lib/modal.php';
}
/**
+1 -1
View File
@@ -32,7 +32,7 @@ if (!defined('WPINC')) {
}
// Load the main plugin class
require_once plugin_dir_path(__FILE__) . 'includes/plugin.php';
require_once plugin_dir_path(__FILE__) . 'includes/Plugin.php';
// Initialize the plugin
// This is a test change for our new workflow