PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.8
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.8
1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 0.8.6 All 33 releases
desktop-mode / includes / rest / README.md

README.md in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.8, at includes/rest/README.md

86 lines 9.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 # `includes/rest/` — REST route map
2
3 Discoverability index for the REST surface. Routes are still registered in their owning subsystem files (where the callback closures and module state live), so moving the `register_rest_route()` calls into a single directory would have been a paperwork rename that broke nothing and improved nothing. This document is the central grep target instead.
4
5 Plugin authors looking for the canonical route URL → handler map start here; the implementation file is one open away.
6
7 ## Namespace
8
9 All in-tree routes register under `desktop-mode/v1`. Extensions are expected to register under `os-<extension>/v1` (declared via the `extensions/base/OpenStation_Extension_Rest` base's `namespace()` method; the base does not enforce a particular namespace — its docblock also permits `desktop-mode/v1`).
10
11 ## Routes
12
13 | Route | Verb | Handler file | Permission |
14 |---|---|---|---|
15 | `/session` | GET / POST / DELETE | `includes/session.php` | logged-in + OpenStation enabled |
16 | `/default-window` | POST | `includes/default-window.php` | logged-in + OpenStation enabled |
17 | `/intros/seen` | POST | `includes/seen-intros.php` | logged-in + OpenStation enabled |
18 | `/intros` | DELETE | `includes/seen-intros.php` | logged-in + OpenStation enabled |
19 | `/os-settings` | GET / POST | `includes/os-settings.php` | logged-in + OpenStation enabled |
20 | `/extended-options` | GET / POST | `includes/extended-options.php` | `manage_options` |
21 | `/pwa-state` | GET / POST | `includes/pwa.php` | logged-in + OpenStation enabled |
22 | `/debug` | GET | `includes/devtools.php` | `manage_options` (filterable via `openstation_debug_rest_permission`) |
23 | `/presence` | GET / POST | `includes/presence.php` | logged-in + OpenStation enabled |
24 | `/oauth/start` | POST | `includes/oauth-relay.php` | logged-in |
25 | `/oauth/callback` | GET | `includes/oauth-relay.php` | public (validated by the state nonce) |
26 | `/term-counts` | GET | `apps/posts/parts/terms-rest.php` | `edit_posts` |
27 | `/tag-cooccurrence` | GET | `apps/posts/parts/terms-rest.php` | `edit_posts` |
28 | `/users` | POST | `apps/users/parts/rest.php` | `create_users` |
29 | `/users/bulk-role` | POST | `apps/users/parts/rest.php` | `promote_users` |
30 | `/users/bulk-delete` | POST | `apps/users/parts/rest.php` | `delete_users` (`remove_users` on multisite) |
31 | `/users/{id}/send-password-reset` | POST | `apps/users/parts/rest.php` | `edit_users` |
32 | `/users/{id}/resend-welcome` | POST | `apps/users/parts/rest.php` | `edit_users` |
33 | `/users/{id}/insights` | GET | `apps/user-edit/parts/insights.php` | `edit_user` on the target user |
34 | `/users/{id}/destroy-sessions` | POST | `apps/user-edit/parts/account.php` | `edit_user` on the target user |
35 | `/users/{id}/application-passwords` | GET / POST | `apps/user-edit/parts/account.php` | `edit_user` on the target user |
36 | `/users/{id}/application-passwords/{uuid}` | DELETE | `apps/user-edit/parts/account.php` | `edit_user` on the target user |
37 | `/comments/bulk` | POST | `apps/comments/parts/rest.php` | `moderate_comments` |
38 | `/comments/reply` | POST | `apps/comments/parts/rest.php` | `edit_posts` |
39 | `/comments/insights/{email}` | GET | `apps/comments/parts/rest.php` | `moderate_comments` |
40 | `/comments/counts` | GET | `apps/comments/parts/rest.php` | `edit_posts` |
41 | `/comments/ai-settings` | GET / POST | `apps/comments/parts/ai-moderation.php` | `manage_options` |
42 | `/content-graph/post-types` | GET | `includes/content-graph/rest.php` | `edit_posts` (filterable via `openstation_content_graph_user_can_use`) |
43 | `/content-graph/nodes` | GET | `includes/content-graph/rest.php` | `edit_posts` (filterable via `openstation_content_graph_user_can_use`) |
44 | `/content-graph/post/{id}` | GET | `includes/content-graph/rest.php` | `edit_posts` (filterable via `openstation_content_graph_user_can_use`) |
45 | `/apps/(?P<app>[a-z0-9][a-z0-9_-]*)/dispatch` | POST | `includes/framework/wordpress.php` | Logged in + the app exists + `App::allows()` (its `capabilities()` and `can()` gate). Every `.os.php` window — Code Blue included, behind Developer mode + `manage_options` (`manage_network_options` on multisite), filterable via `openstation_code_blue_user_can_use` — is served by this one route; there are no per-app routes. |
46 | `/comment-stats/{id}` | GET | `includes/my-wordpress/comment-stats.php` | `edit_posts` (filterable via `openstation_my_wordpress_user_can_use`) + parent post readable: `read_post`, but `edit_post` when the parent is still sealed by a password (a caller who already entered it reads on `read_post` like anyone else) or when its post type has no readable front end, and `moderate_comments` when the parent is gone |
47 | `/term-stats/{taxonomy}/{id}` | GET | `includes/my-wordpress/term-stats.php` | logged-in + `read` |
48 | `/user-stats/{id}` | GET | `includes/my-wordpress/user-stats.php` | logged-in |
49 | `/user-footprint/{id}` | GET | `includes/my-wordpress/user-footprint.php` | logged-in |
50 | `/media-usage/{id}` | GET | `includes/my-wordpress/media-usage.php` | `read_post` on the attachment |
51 | `/recycle-bin/*` | various | `includes/recycle-bin/rest.php` | `delete_posts` (per-route gate) |
52 | `/files/*` | various | `includes/desktop-files/rest.php` | logged-in + OpenStation enabled (share routes add a sharing gate) |
53 | `/ai/search` | POST | `includes/ai-copilot/search.php` | logged-in + AI feature flag |
54 | `/ai/platform-settings` | GET / POST | `includes/ai-copilot/platform-settings.php` | `manage_options` |
55 | `/games/{game}/scores` | GET / POST | `includes/games/rest.php` | logged-in + OpenStation enabled + `read` (filterable via `openstation_games_rest_permission`) |
56 | `/games/{game}/playtime` | POST | `includes/games/rest.php` | same games gate |
57 | `/games/playtime` | GET | `includes/games/rest.php` | same games gate |
58 | `/games/challenges` | GET / POST | `includes/games/rest.php` | same games gate (create also passes `openstation_games_can_challenge`) |
59 | `/games/challenges/{id}/accept` | POST | `includes/games/rest.php` | same games gate + challenge recipient |
60 | `/games/challenges/{id}/decline` | POST | `includes/games/rest.php` | same games gate + challenge recipient |
61 | `/games/challenges/{id}/complete` | POST | `includes/games/rest.php` | same games gate + challenge recipient |
62 | `/games/users/search` | GET | `includes/games/rest.php` | same games gate |
63 | `/agents` | GET / POST | `includes/agents/rest.php` | GET `edit_posts`, POST `edit_users` (both filterable; whole module behind the `agents` extended option) |
64 | `/agents/{id}` | GET / POST / DELETE | `includes/agents/rest.php` | GET `edit_posts`, POST/DELETE `edit_users` (filterable) |
65 | `/agents/{id}/invoke` | POST | `includes/agents/rest.php` | `edit_posts` (filterable via `openstation_agents_user_can_invoke`), then the per-agent gate `openstation_agent_user_can_invoke_agent()` (honours the trigger's `capability`) + per-invoker and per-agent rate limits. The run itself is ceilinged at the caller's own capabilities — see [](../../docs/agents-security.md`docs/agents-security.md`](../../docs/agents-security.md](../../docs/agents-security.md) |
66 | `/agents/{id}/jobs/{jobId}` | GET | `includes/agents/jobs.php` | Authenticated invoker + exact job owner and agent match. Constant-cost status read, no worker dispatch. |
67 | `/agents/abilities` | GET | `includes/agents/rest.php` | `edit_posts` (filterable) |
68 | `/agents/draft` | POST | `includes/agents/rest.php` | `edit_users` (filterable). One AI generate call with a strict answer schema; creates nothing. `503` without the AI Client, `502` when the provider fails or answers unreadably |
69 | `/agents/trigger-kinds` | GET | `includes/agents/rest.php` | `edit_posts` (filterable) |
70 | `/agents/hooks-catalogue` | GET | `includes/agents/rest.php` | `edit_posts` (filterable) |
71 | `/agents/roles` | GET | `includes/agents/rest.php` | `edit_users` (filterable) |
72
73 ## Conventions
74
75 - **Nonce.** Every state-changing route requires `X-WP-Nonce` (the standard REST nonce). Read routes that depend on per-user state also require it.
76 - **Permission.** Permission callbacks use either `is_user_logged_in()` + capability checks or domain predicates. Shell-internal endpoints that only touch the caller's own per-user desktop state (`/session`, `/default-window`, `/intros`, `/os-settings`, `/pwa-state`, `/presence`) share the `openstation_rest_require_enabled()` gate (`includes/helpers.php`): logged-in **and** `openstation_is_enabled()`, returning `401` when logged out and `403` when OpenStation is off. `read` alone is deliberately not enough — every authenticated role carries it. Filtering with `openstation_*` hooks lets plugins extend or harden access.
77 - **Errors.** Failures return `WP_Error` with a stable `code`, a translated `message`, and a `data: { status: <int> }` block. Codes are documented per-endpoint in `docs/hooks-reference.md`.
78
79 ## Why no central registration
80
81 PHP `register_rest_route()` calls execute on `rest_api_init`. The callback closures in the existing files capture per-module state — the recycle-bin store, the desktop-files registry, the AI provider — that lives in the same module. Moving the registration calls out of those files would force every callback to re-look-up its dependencies, increasing surface area without reducing coupling. The route → handler-file map above is the discoverability win we wanted; the per-module registrations are the layout that minimises blast radius.
82
83 If a future extension adds REST routes that don't fit any existing module, the `extensions/base/OpenStation_Extension_Rest` base class is the cheapest path. See `extensions/base/README.md`.
84
85 Agent invocation supports `async: true` plus a UUID `requestId`, returning HTTP 202. See [](../../docs/architecture.md#async-agent-jobsasync jobs](../../docs/architecture.md#async-agent-jobs](../../docs/architecture.md#async-agent-jobs) for the status contract and worker requirements.
86