Skip to content

major update - #23

Merged
soderlind merged 11 commits into
mainfrom
improve
Jul 24, 2026
Merged

major update#23
soderlind merged 11 commits into
mainfrom
improve

Conversation

@soderlind

Copy link
Copy Markdown
Owner

This pull request introduces a major update (v0.5.0) to the Admin Coach Tours plugin, focusing on a complete migration to the new WordPress 7 AI Connector system, enhanced task libraries, improved UI/UX for tours, and automated GitHub-based release updates. It also removes legacy code and configuration for direct API key management, streamlining both security and user experience.

AI System Migration and Cleanup

  • Migrated all AI features to use the WordPress 7 AI Connector (wp_get_connectors / wp_ai_client_prompt), removing bundled OpenAI/Azure/Anthropic providers, direct API key storage, and encryption. The plugin now requires WP 7.0+ and at least one configured AI connector. [1] [2] [3] [4] [5] [6] [7]
  • Added a one-time upgrade routine to remove legacy AI options and API keys from the database.

Release Automation and Self-Updates

  • Added GitHub Actions workflows to build and attach distributable plugin zips on release and via manual trigger, using a .distignore file to exclude development files. [1] [2] [3]
  • Integrated automatic plugin self-updates from GitHub releases using the WordPress Plugin GitHub Updater. [1] [2]

Task Library and UI Enhancements

  • Expanded the predefined task library to 20+ tasks, reordered categories (Text first), and improved task categorization and icons. [1] [2] [3]
  • The Coach panel now surfaces /command as a header above instructions, improving clarity for command-based steps. [1] [2]
  • Removed the "Next" arrow button to prevent skipping ahead before a block exists; only manual or final steps show footer controls. [1] [2] [3] [4]

Requirements and Documentation

  • Updated minimum requirements to WordPress 7.0+ and PHP 8.3+, and revised documentation and plugin headers to match. [1] [2] [3] [4] [5]

Bug Fixes and Behavior Improvements

  • Fixed REST API validation for null editorContext/failureContext, improved block selection fallback, and clarified tour progression and copy.

These changes modernize the plugin, improve maintainability, and align with current WordPress best practices.

soderlind added 11 commits July 24, 2026 01:07
Replace the plugin's custom provider/API-key management with the WordPress
Core AI connector API (wp_get_connectors / wp_ai_client_prompt), following
the approach in soderlind/llms-md.

- Rewrite AiManager as a thin orchestrator over wp_ai_client_prompt()
  ->generate_text(); connector detection via wp_get_connectors(), JSON
  parsing with Markdown code-fence stripping, reusing existing draft/tour
  validation. suggest_completion stays pure-PHP heuristics.
- Delete OpenAiProvider, AzureOpenAiProvider, AnthropicProvider,
  AiProviderInterface and Security\Encryption (keys now owned by Core).
- Slim SettingsPage: connector status + enable toggle + connector-ID
  provider dropdown + optional model override (act_ai_provider / act_ai_model).
- AiController: generate_tour calls AiManager directly; get_status reports
  connector-based availability.
- Bump Requires at least to 7.0, drop the sodium requirement, add one-time
  upgrade cleanup of legacy encrypted-key options, expand uninstall.php.
- Add filters: admin_coach_tours_ai_connector_configured,
  admin_coach_tours_ai_provider_id, admin_coach_tours_ai_model.
- Add AiManagerTest (mocks wp_ai_client_prompt); update docs.

Assisted-by: GitHub Copilot:Claude Opus 4.8
Turn the shallow AiController into a thin HTTP adapter by concentrating the
tour-generation implementation behind small interfaces (architecture review
candidates A–E).

- TourGenerator: deep module `generate(TourRequest): array|WP_Error` owning
  cache, RAG retrieval, prompt assembly, AI call, and validation. AiManager is
  injected (no singleton), so the pipeline is testable off the REST stack.
- TourRequest: immutable value object; `from_rest()` owns the full input
  surface (editorContext/failureContext sanitization moved out of the
  controller). Routes.php now declares those args — the route contract is
  complete.
- TaskPrompts owns prompt formatting: `get_system_prompt()` takes structured
  editor/failure context arrays and formats them internally (the format_*
  helpers moved out of the controller).
- TourSchema: single source of truth for allowed locator/precondition/
  completion types, shared by TaskPrompts::get_tour_schema (enums) and
  AiManager::validate_and_sanitize_tour — no more drift.
- AiController: thin adapter (parse -> generate -> map_error).
- JS store: fetchAiTasks routes /ai/tasks through the store control seam
  (PupilLauncher stops calling apiFetch directly); locale is threaded through
  requestAiTour so controls.js no longer reads window.adminCoachTours.

Tests: add TourRequestTest and TourGeneratorTest; slim AiControllerTest;
move format/sanitize tests to their new homes. PHP 59 + JS 86 green.

Assisted-by: GitHub Copilot:Claude Opus 4.8
The generate-tour args declared these as `type => object`, but the client
sends `failureContext: null` (and editorContext can be null), which WP REST
rejects with `rest_invalid_param` (400), aborting tour generation. Widen the
type to `[ 'object', 'null' ]` so the contract stays explicit while accepting
null. TourRequest already handles null.

Assisted-by: GitHub Copilot:Claude Opus 4.8
When the tour ends, return the caret to the block the user was on instead of
leaving focus on nothing.

- Add exported focusCurrentBlock() (runtime/applyPreconditions.js) that focuses
  the currently selected block via the existing focusBlockElement logic
  (handles the editor iframe and places the caret at the end).
- Call it on both end paths in TourRunner: handleStop (X/close button) and the
  last-step completion branch (which does not fire onLeaveStep, so the block is
  still selected).

Assisted-by: GitHub Copilot:Claude Opus 4.8
Coach panel:
- Surface the "/command" (e.g. /image) as a header above the instruction so
  it's easy to spot.
- Remove the arrow "Next" button; auto-advancing steps no longer let users
  skip ahead to a step that expects an already-inserted block. Only manual /
  last steps show a footer control (Continue/Finish); the footer is hidden
  otherwise.

Task launcher:
- Order categories explicitly with Text first (was driven by task array order).
- Fix CATEGORY_ICONS whose keys didn't match the real categories
  (text/media/design/embed now each get an icon instead of the fallback).

Tasks (TaskPrompts::get_tasks):
- Add "Add a paragraph" (text) with a bespoke single-step instruction that
  does not use the "/" inserter (the empty paragraph already exists).
- Add code, separator, details, audio, file, group, spacer, and embed-from-URL
  tasks across the text/media/design/embed categories.

Assisted-by: GitHub Copilot:Claude Opus 4.8
- resolveTarget: `wpBlock: "selected"` now falls back to the last-selected
  block (tracked in onLeaveStep before clearSelectedBlock), then the last
  appeared block, then the sole block. Fixes the false "Could not find the
  target element" on confirmation steps that reference the same block after
  the tour deselects it between steps.
- PupilLauncher: hide the launcher (light bulb) when the editor is in code
  (text) mode, via core/edit-post getEditorMode; reactive to mode toggles.
- TaskPrompts: forbid positional words ("below"/"above"/etc.) in tour copy
  (global rule + add-paragraph instruction) since the panel/highlight move.
  Bump the tour cache version to invalidate stale cached tours.

Assisted-by: GitHub Copilot:Claude Opus 4.8
Previously, if a step expected a specific block (e.g. Image) but the user
inserted something else (e.g. Gallery), target resolution failed and the user
was shown a "Try Again" that could never succeed, then a hard failure.

Detect divergence in TourRunner: when the step's expected block type is known
and absent, but the editor contains a different non-empty block, stop the tour
immediately with a clear message ("This tour was for adding a X block, but a
different block was added..."). Genuine timing failures (expected block just
not rendered yet, nothing else added) keep the existing Try Again path.

Assisted-by: GitHub Copilot:Claude Opus 4.8
On the final step, clicking the highlighted block (including its inner
controls like Upload/Media Library) now finishes the tour, in addition to the
Finish button. A 400ms grace period prevents the click that advanced into the
last step from closing it immediately, and the listener/timer are cleaned up
on step change or unmount.

Assisted-by: GitHub Copilot:Claude Opus 4.8
Version bump to 0.5.0 across the plugin header, readme.txt, and package.json,
with changelog entries in CHANGELOG.md and readme.txt.

Also adds GitHub-based self-updates:
- Require soderlind/wordpress-github-updater and initialise GitHubUpdater in the
  bootstrap (tracks the `main` branch, 6h check period, matches
  admin-coach-tours.zip release assets).
- Add .github/workflows/on-release-add.zip.yml and manually-build-zip.yml to
  build (npm + composer --no-dev) and attach the plugin zip to releases.
- Add .distignore for the packaged zip.

Docs: update AI-ARCHITECTURE.md, README.md, and readme.txt to the WP 7 AI
Connector / deep-module architecture and the current task list; mark PLAN.md as
historical; refresh Installation with the release-zip / self-update flow.

Assisted-by: GitHub Copilot:Claude Opus 4.8
The 'should define category icons' test cold-imports the full
@wordpress/components tree and some tests wait on real timers; on slower CI
runners (seen on Node 22) these can exceed vitest's 5s default and report as an
error. Raise testTimeout/hookTimeout to 30s. Local suite stays green (86/86).

Assisted-by: GitHub Copilot:Claude Opus 4.8
CI runs Node 20/22 which ship npm 10; that npm required yaml@2.9.0 which was
missing from the lock (generated by local npm 11), failing 'npm ci' with
'package.json and package-lock.json ... not in sync'. Regenerated the lock with
npm 10 so it is accepted by both npm 10 and 11.

Assisted-by: GitHub Copilot:Claude Opus 4.8
@soderlind
soderlind merged commit c0475ae into main Jul 24, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant