Commit Graph
5 Commits
Author SHA1 Message Date
janniclas.loosenandClaude Opus 5.5 4f9a47fe32 feat: content-create and content-update with schema validation
All-or-nothing writes: validation (fields, terms, featured image, parent,
template) before any write; failed extras delete the new draft (create) or
restore revision, old columns, fields, terms and featured image (update).
content-update requires rev; Rev::ofPost covers content, title, excerpt,
status and post_modified_gmt. MetaFieldSource::write() now throws on failure.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-25 23:01:48 +02:00
janniclas.loosenandClaude Opus 5.5 1df655a74e fix: fail closed on permission() exceptions, harden RequestContext flag reset
- AbilityRegistrar: wrap permission_callback in try/catch(Throwable) like
  execute_callback, so a throwing permission() denies (Errors::internal())
  instead of skipping rest_request_after_callbacks and leaving
  RequestContext's flag set for a later request in the same PHP worker.
- RequestContext::recordRoute() now recomputes the flag (and bearer token)
  unconditionally on every matched REST request instead of only setting it
  true for our own route, so a stale true left behind by an earlier request
  is reset by the next non-matching one (fail closed, defense in depth).
- RequestContext::recordRoute() matches the Authorization "Bearer" scheme
  case-insensitively.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-25 21:51:41 +02:00
janniclas.loosenandClaude Opus 5.5 f63d35c2f8 feat: structured errors with hint, ToolResult, cursor pagination
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-25 21:37:42 +02:00
janniclas.loosenandClaude Opus 5.5 0e3332ad3e fix: close etappe-0 whole-branch review findings
- Autoloader: add automattic/jetpack-autoloader and load
  vendor/autoload_packages.php; require wordpress/mcp-adapter directly (^0.5).
- ServerRegistrar: make the adapter create_server() call and the
  OAuthServerRegistrar class_exists() check injectable so createServer()'s
  unhook-before-create ordering and the "mcp-oauth absent" branch are unit
  tested; add a smoke-test check that booting REST triggers no
  _doing_it_wrong().
- mcp-smoke.sh: assert mcp-adapter's default server route 404s, and that the
  subscriber role-gate denial actually carries our/the adapter's denial text
  (not just any isError/error).
- Guard tests/Integration/mint-token.php and tec-probe.php with
  `defined('WP_CLI') && WP_CLI || exit;`; add .gitattributes export-ignore
  for tests/docs-superpowers/.superpowers/phpunit/phpcs config.
- Security: add Server/RequestContext, tracking via
  rest_request_before_callbacks whether the current REST dispatch is our
  OAuth-protected /mcp/mcp-oauth-server route; AbilityRegistrar's
  permission_callback now denies (after the role gate) when abilities are
  invoked outside that route. Wired in Plugin::boot().
- Minors: single Plugin::VERSION constant used by ServerRegistrar;
  IntegrationRegistry caches its computed abilities list; tec-probe.php
  checks wp_insert_post's result and cleans up its probe post in a
  try/finally.

composer test: 47/47 green. composer lint: clean. Full mcp-smoke.sh run ends
ALL CHECKS PASSED (plus the expected /.well-known WARN).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-25 19:23:09 +02:00
janniclas.loosenandClaude Opus 5.5 3b7fabf17a feat: ability and integration infrastructure
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-25 15:27:08 +02:00