Skip to content

Latest commit

 

History

History
173 lines (139 loc) · 9.7 KB

File metadata and controls

173 lines (139 loc) · 9.7 KB

Development

Quick start

git clone https://github.com/ateeducacion/wp-decker.git
cd wp-decker
composer install
make up

WordPress: http://localhost:8888
Credentials: admin / password

Useful Make targets

Command Description
make up Start the development environment
make down Stop it
make test Run PHPUnit tests
make lint PHP_CodeSniffer
make fix Auto-fix coding standards
make check Full check (lint + tests + plugin-check)
make pot Regenerate translation template
make package VERSION=x.y.z Build a release ZIP
make help List all targets

Coding standards

  • WordPress Coding Standards
  • English for code, comments and identifiers
  • Spanish for user-facing strings
  • Every new/changed string must update the .pot / .po / .mo in the same commit (make check-untranslated)

See AGENTS.md and CONVENTIONS.md for detailed agent and project conventions.

Agent skills

Skills are folders of instructions an AI coding agent loads on demand. They live under .agents/skills/ (Copilot, Codex, Cursor) and .claude/skills/ (Claude Code). Grok Build reads Claude Code skills automatically. Install and refresh them with the GitHub CLI:

gh skill add WordPress/agent-skills wp-performance --agent github-copilot
gh skill add WordPress/agent-skills wp-performance --agent claude-code
gh skill update --all

gh skill add is an alias of gh skill install. Each host gets its own copy; older Claude Code entries remain as symlinks into .agents/skills/. Do not convert one layout into the other by hand.

Skill Read it before
wp-plugin-development Touching hooks, activation/uninstall, the Settings API, options, cron or release packaging
wp-rest-api Adding or debugging routes: register_rest_route, permission_callback, schema/args, register_meta, show_in_rest
wp-plugin-directory-guidelines Editing readme.txt, license headers or plugin naming — what make check-plugin enforces
blueprint Editing blueprint.json or the Playground preview
wp-performance Profiling or improving backend performance
wp-project-triage Inspecting what kind of WordPress repo this is before changing tooling
wp-plugin-security Writing or reviewing code that handles input, output, AJAX/REST, capabilities or files
security-audit Hunting vulnerabilities and validating findings

The WordPress ones come from WordPress/agent-skills (GPL-2.0-or-later); wp-plugin-security from fernandotellado/ai-skills; security-audit from cloudflare/security-audit-skill.

All of them are vendored verbatim. Do not reformat or patch them locally — gh skill update is how they stay current.

Nothing under .agents/, .claude/, AGENTS.md or CLAUDE.md reaches the release ZIP; .gitattributes marks it export-ignore.

Available hooks

Actions

do_action( 'decker_task_created', $task_id );
do_action( 'decker_task_updated', $task_id );
do_action( 'decker_stack_transition', $task_id, $source_stack, $target_stack );
do_action( 'decker_task_completed', $task_id, $target_stack );
do_action( 'decker_user_assigned', $task_id, $user_id );

Filters

apply_filters( 'decker_save_task_send_response', true );

What counts as a stable surface

The hooks above, plus Decker_Task_Writer::create_or_update_task( array $args ), are what integrations should build on. Everything else — class names, method names, which class registers which callback — is internal and gets reorganised as classes grow.

Most public methods on these classes are public only because WordPress needs to call them as hook callbacks. Calling them directly, or unhooking them by name, is not supported.

Class reorganisations

Symbols that have moved, so an integration that referenced the old location can find the new one. None of these changed behaviour; only their owner changed.

Was Is now
Decker_Boards::add_color_field() / edit_color_field() / save_color_meta() Decker_Board_Term_Fields (extends Decker_Term_Color_Field)
Decker_Labels::add_color_field() / edit_color_field() / save_color_meta() Decker_Term_Color_Field
Decker_Kb::track_last_editor() / get_last_editor() / get_latest_revision_id() / get_revision_admin_url() Decker_Kb_Revisions
Decker_Events::add_meta_boxes() / display_users_meta_box() / render_event_details_meta_box() Decker_Event_Meta_Box
Decker_Events::hide_visibility_options() / add_custom_columns() / render_custom_columns() Decker_Event_Admin_Screen
Decker_Admin_Settings::*_render() (16 field renderers) / section callbacks Decker_Admin_Settings_Fields (single public render() dispatcher)
Decker_Admin_Settings private validators Decker_Admin_Settings_Validator::validate()
Decker_Notification_Handler::add_notification_to_user() / remove_notification_from_user() Decker_Notification_Store
Decker_Notification_Handler::MAX_NOTIFICATIONS (public constant) Decker_Notification_Store::MAX_NOTIFICATIONS
Decker_Notification_Handler::heartbeat_received() / modify_heartbeat_settings() / ajax_*() Decker_Notification_Ajax
Decker_Events meta-saving pipeline (bodies; process_and_save_meta() / save_event_meta() stay as public delegators) Decker_Event_Meta_Saver
Decker_Email_To_Post attachment pipeline (upload_attachment() and helpers) Decker_Email_Attachment_Uploader
Decker_Email_To_Post board directive resolution Decker_Email_Board_Resolver
Decker_Demo_Data task/comment seeding and randomness helpers Decker_Demo_Tasks, Decker_Demo_Randomizer
Decker_Calendar::handle_ical_request() / add_ical_endpoint() and access checks Decker_Calendar_Ical_Feed
Decker_Calendar::get_cached_ical() / flush_cache_*() Decker_Calendar_Cache
Decker_Kb::save_article() and the write path Decker_Kb_Article_Writer
Decker_Kb::reorder_articles() and sibling renumbering Decker_Kb_Reorder
TaskManager "for today" query bodies (public entry points stay as delegators) Decker_Task_Today_Query, Decker_Task_Date_Relations
Decker_Tasks::clone_task() and its private readers Decker_Task_Clone
Decker_Tasks::merge_tasks() and the merge pipeline Decker_Task_Merge
Decker_Tasks lock REST routes + refresh_task_lock_heartbeat() Decker_Tasks_Rest_Locks
Decker_Tasks today REST routes (handle_task_today(), mark/unmark relations) Decker_Tasks_Rest_Today
Decker_Tasks field-op REST routes + REST insert guards Decker_Tasks_Rest_Ops
Decker_Tasks::search_tasks() / clone + merge REST transport Decker_Tasks_Rest_Tools
Decker_Tasks::make_permission_callback() / lock_error_response() Decker_Tasks_Rest_Support (public statics)
Decker_Tasks order/stack engine (update_task_stack_and_order(), handle_fix_order(), reorder_tasks_in_stack(), get_new_task_order()) Decker_Task_Order
Decker_Tasks order hook reactions (post-data filter, board/stack term changes) Decker_Task_Order_Hooks
Decker_Tasks edit-screen meta boxes (add_meta_boxes() and the eight display/render methods) Decker_Task_Meta_Boxes
Decker_Tasks admin list table (columns, sorting, taxonomy/status filters, row actions) Decker_Task_Admin_List
Decker_Tasks edit-screen chrome (visibility/menu-order/permalink hiding, publish box title, Gutenberg disable, Add New removal) Decker_Task_Admin_Chrome
Decker_Public::enqueue_scripts() body Decker_Public_Assets
Decker_Tasks::save_meta() and the private meta-save pipeline Decker_Task_Meta_Saver
Decker_Tasks::handle_save_decker_task() + lock guards Decker_Task_Ajax_Save (no delegator — direct callers must retarget)
Decker_Tasks $_POST readers Decker_Task_Request_Reader
Decker_Tasks::add_user_date_relation() / remove_user_date_relation() Decker_Task_Today_Manager::mark_for_today() / unmark_for_today()
Decker_Tasks::create_or_update_task() and the write pipeline Decker_Task_Writer::create_or_update_task( array $args ) — signature changed, no delegator
Task::render_task_card() and the card display helpers (get_card_background_style(), get_due_css_class(), render_card_board_name(), render_card_comments_counter(), render_card_labels_counter(), render_people_avatars(), get_relative_time(), get_formatted_date(), pastelize_color()) Decker_Task_Card_Rendererpastelize_color() became a public static (parameter-pure); get_relative_time() / get_formatted_date() stay public instance methods
Task::render_task_menu() and the menu-item builders (get_menu_task_url(), get_admin_menu_items(), get_owner_menu_items(), get_archive_menu_item(), get_assignment_menu_items(), print_menu_dropdown()) Decker_Task_Menu_Renderer
Task::get_people_users() / get_people_names() / get_user_history_with_objects() Decker_Task_People_View

Note that unhooking one of these by name fails silently rather than fatally:

// No longer matches anything; the field still renders.
remove_action( 'decker_board_add_form_fields', array( $boards, 'add_color_field' ) );

To suppress a field, unhook the current owner, or filter the markup it produces.

Testing

Tests live under /tests/ and use factories.
Run with make test.

Contributing

  1. Create a feature branch.
  2. Make your changes following the coding standards and translation rules.
  3. Run make check.
  4. Open a Pull Request.