[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-automattic-create-vip-workflows-agent":3,"mdc-b1qbjp-key":35,"related-repo-automattic-create-vip-workflows-agent":7814,"related-org-automattic-create-vip-workflows-agent":7854},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":22,"repoUrl":23,"updatedAt":24,"license":25,"forks":26,"topics":27,"repo":30,"sourceUrl":33,"mdContent":34},"create-vip-workflows-agent","scaffold VIP Workflows agent plugins","Scaffold a VIP Workflows agent plugin. Use when the user wants to create a research agent, a story discovery source, an AI-stage agent, or a combined agent that provides multiple capabilities for VIP Workflows.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"automattic","Automattic","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fautomattic.png",[12,16,19],{"name":13,"slug":14,"type":15},"WordPress","wordpress","tag",{"name":17,"slug":18,"type":15},"Plugin Development","plugin-development",{"name":20,"slug":21,"type":15},"Agents","agents",150,"https:\u002F\u002Fgithub.com\u002FAutomattic\u002Fvip-go-mu-plugins-built","2026-09-04T08:01:04.234021",null,38,[28,29,14],"vip","vip-go",{"repoUrl":23,"stars":22,"forks":26,"topics":31,"description":32},[28,29,14],"The generated repo for mu-plugins used on the WPVIP platform.","https:\u002F\u002Fgithub.com\u002FAutomattic\u002Fvip-go-mu-plugins-built\u002Ftree\u002FHEAD\u002Fvip-integrations\u002Fvip-workflows-0.0\u002Fskills\u002Fcreate-agent","---\nname: create-vip-workflows-agent\ndescription: >-\n  Scaffold a VIP Workflows agent plugin. Use when the user wants to create\n  a research agent, a story discovery source, an AI-stage agent, or a\n  combined agent that provides multiple capabilities for VIP Workflows.\n---\n# Create a VIP Workflows Agent\n\nAn **agent** is a standalone WordPress plugin that extends VIP Workflows. All agents appear as cards on the unified **Integrations > Agents** tab. An agent can provide one or more of these capabilities:\n\n- **Research** — runs *after* an editor has a seed, inside an ideation project. Returns cards (articles, discussions, media) that populate the project's mood board.\n- **Discovery** — runs *before* an editor has a seed, on the ideation landing page. Returns story prompts that editors can click to spawn a new project.\n- **Stage** — runs when a post enters an AI-owned workflow stage. Returns a pass\u002Ffail verdict the stage's routing map turns into an exit transition; execution errors follow the stage's optional error route or fail in place.\n\nA single plugin can provide research only, discovery only, stage only, or a combination. See `docs\u002Fspecs\u002Fshipped\u002Funified-assistants-tab.md` for the underlying architecture.\n\n## Decide the Shape First\n\nBefore writing any code, decide which capabilities the agent offers:\n\n| Capability | When it runs | Returns | Registration hook | Required callbacks |\n|------------|--------------|---------|-------------------|--------------------|\n| **Research** | Inside a project (after seed) | Cards for mood board | `wp_abilities_api_init` | `execute_callback` |\n| **Discovery** | Landing page (before seed) | Story prompts | `vip_workflows_register_discovery_providers` | `seed` + one or both of `recommend` \u002F `search` (+ `filters` if `search`) |\n| **Stage** | When a post enters an AI-owned workflow stage | `{ status: pass\\|fail, summary }` | `vip_workflows_register_abilities` | `execute_callback` |\n\nDiscovery itself has two independent sub-features declared in the `features` array:\n\n- **`recommend`** — returns a curated list for the landing page. Called on page load, no user query. Think \"what's newsworthy right now.\"\n- **`search`** — returns results matching a user query and filter selections, powering the \"Browse more…\" modal. Requires `filters` callback alongside.\n\nA discovery provider can declare `recommend` only, `search` only, or both. Most full-featured sources do both.\n\n## Stage Agents (AI-owned workflow stages)\n\nA **stage agent** runs automatically when a post enters a workflow stage that has been marked as AI-owned. It inspects the post, optionally rewrites the content (saving a revision), and returns an outcome. The stage's routing table then maps that outcome to one of the stage's configured transitions — so the agent participates in transitions exactly like a human stage (bump back, advance to a human, or move on).\n\nA stage agent is a normal ability plus an agent manifest. It has different requirements from research and discovery agents:\n\n1. **Input contract** — take `post_id`; read the post through `VIPWorkflows\\Abilities\\Agents\\StageAgent::read_post()` so permissions and empty-content errors match core stage agents.\n2. **Stage metadata** — set `meta.stage_eligible => true` and include `'stage'` in `meta.supports` alongside `'workflow'`. The Sequence editor's agent picker and `\u002Fvip-workflows\u002Fv1\u002Fabilities?context=stage` only list abilities with both signals.\n3. **Agent manifest** — register on `vip_workflows_register_assistant_meta` with `capabilities => array( 'stage' )`. This marks the card as **Available in AI stage** only when the referenced ability is also stage-eligible.\n4. **Output contract** — return `{ status, summary, ... }` where `status` is either `pass` or `fail`. Stage agents make a binary editorial judgment: return `pass` when the post is safe to continue on the success path, or `fail` (with a clear `summary`\u002F`issues` payload) when it should not. Return a `WP_Error` on failure; the runner routes that through the stage's `error` destination.\n5. **Mutability contract** — read-only agents should declare `annotations.readonly => true`. Mutating agents must write through `StageAgent`: use `StageAgent::write_content()` to rewrite the body, or `StageAgent::write_block_notes()` to annotate blocks with native editorial notes (`comment_type => 'note'`, anchored via the block's `metadata.noteId`). Both sanitize content and attribute the change to the acting user. A note-writing agent is not read-only (`annotations.readonly => false`). Native notes render in the editor's Comments panel for post types that declare `editor => notes` support (`post`\u002F`page` do by default; a custom type needs `add_post_type_support( $type, 'notes' )`).\n\n**Routing** (authored on the stage, not the agent): `agent.routing = { pass, fail, error }`, where each value is a status key that must be one of that stage's configured transitions. Every key is optional, `error` included: when `error` is routed, the runner sends a `WP_Error`, an invalid contract result, or any unrouted outcome there; without it, an errored run fails in place and the editor offers a \"go back to the previous stage\" action. The engine (`StageAgentRunner`) runs the agent asynchronously on stage entry, gates human transitions while it runs (and while it sits failed with a go-back available), and performs the exit transition as the agent — humans can only ever take the routed destinations.\n\nIn the Sequence editor these are authored on the canvas, not in a form: choosing an agent in the stage inspector is what makes the stage AI-owned, and the node then carries three colored source handles — green `pass`, red `fail`, amber `error`. Dragging one onto another stage sets that outcome's destination and creates the transition it travels on. The inspector reads the routes back but does not edit them.\n\n**An AI stage's other transitions are disabled.** The agent owns the way out, so any transition no outcome routes along is inert: `StatusManager::get_available_transitions()` withholds it (the block editor offers no buttons while the agent works), and the canvas draws it dashed and grey. Nothing is deleted — the transition keeps its roles, tools, and notifications, and goes live again the moment an outcome is routed along it or the agent is taken off the stage. The withholding is scoped to a run actually being in flight: a failed run, or a stage that gained its agent while posts were already sitting in it, hands the transitions back rather than stranding the post.\n\n> Audit logging and revision attribution for agent stages are tracked separately.\n\n> **Agent stages are not reproducible.** `StageAgent::generate()` requests no sampling temperature and offers no way to ask for one, so identical inputs may produce different output — including a different `pass`\u002F`fail` verdict on the same post. Mechanical stages (reformatting, tag sanity) briefly pinned temperature to 0 and did promise stable output; that promise is withdrawn. Newer Claude models refuse any request carrying the option, answering with HTTP 400 rather than ignoring it, and the AI Client's model metadata cannot be used to send it selectively — the Anthropic provider applies one hardcoded option list to every model it enumerates, advertising `temperature` as supported even where the API rejects it. Sending it only to models believed to accept it would be a guess, so it is not sent at all. Do not write an agent whose correctness depends on run-to-run stability.\n\n## Requirements\n\nBefore starting, gather from the user:\n\n1. **Shape** — research, discovery, stage, or a combination?\n2. **For discovery** — does it support `recommend`, `search`, or both?\n3. **For stage** — read-only or mutating? A binary `pass`\u002F`fail` judgment, and what data should appear in the result payload?\n4. **For stage** — what post inputs and settings does it need? Stage agents should always require `post_id`; optional settings belong in the agent's `settings_schema` or in the stage's `agent.settings`.\n5. **Data source** — what API or service? (e.g., Reddit, PubMed, Foresight News, a wire service, an internal CMS, or an AI prompt over the current post)\n6. **Plugin slug** — e.g., `workflow-agent-reddit`, `workflow-agent-copy-edit`, or `workflow-qwoted` for combined\n7. **Namespaced IDs** — ability ID like `workflow-agent-reddit\u002Freddit` (research), `workflow-agent-copy-edit\u002Fcopy-edit` (stage), or provider slug like `my-news-source` (discovery)\n8. **Icon** — an icon slug (e.g. `'search'`, `'calendar'`), from the set in\n   `src\u002Fadmin\u002Fcomponents\u002Fideation\u002Fassistant-icon.js`. Not an emoji: the admin\n   renders these through `@wordpress\u002Ficons`, and an unknown slug renders nothing.\n9. **Credentials?** — does it need an API key? Determines `settings_schema` and `availability_callback` \u002F `is_configured`. Where does the key come from — the agent's own card fields (`RequirementFactory::in_card()`), a service the plugin reads through `VIPWorkflows\\AI\\Credentials` (`RequirementFactory::missing_credential()`), or nowhere the user can act on (`unsupported_environment()` \u002F `dependency()`)? See [Availability](#availability)\n\n## Plugin Structure\n\n```\nworkflow-{name}\u002F\n  workflow-{name}.php   # Main plugin file (single file is fine for most agents)\n```\n\nThe plugin directory lives alongside `vip-workflows\u002F` in the same parent directory (not inside it).\n\nNaming conventions (not enforced, but keep things scannable):\n\n- Research-only: `workflow-agent-{name}` (e.g., `workflow-agent-wikipedia`)\n- Stage-only: `workflow-agent-{name}` (e.g., `workflow-agent-copy-edit`)\n- Discovery-only: `workflow-discovery-{name}` (e.g., `workflow-discovery-newswire`)\n- Both: `workflow-{name}` (e.g., `workflow-qwoted`)\n\n## Boilerplate: Research-Only\n\nUse this when the agent only runs during ideation on the mood board.\n\n```php\n\u003C?php\n\u002F**\n * Plugin Name: Workflow Agent: {Display Name}\n * Description: Research agent that searches {data source} during ideation.\n * Version: 1.0.0\n * Requires Plugins: vip-workflows\n * Text Domain: workflow-agent-{name}\n *\n * @package WorkflowAgent{PascalName}\n *\u002F\n\ndeclare( strict_types=1 );\n\nnamespace WorkflowAgent{PascalName};\n\nif ( ! defined( 'ABSPATH' ) ) {\n    exit;\n}\n\nadd_action( 'wp_abilities_api_init', __NAMESPACE__ . '\\register' );\n\nfunction register(): void {\n    if ( ! function_exists( 'vip_workflows_register_ability' ) ) {\n        return;\n    }\n\n    vip_workflows_register_ability(\n        'workflow-agent-{name}\u002F{slug}',\n        array(\n            'label'               => __( '{Display Name}', 'workflow-agent-{name}' ),\n            'description'         => __( '{One-line description of what this searches.}', 'workflow-agent-{name}' ),\n            'category'            => 'research',\n            'input_schema'        => array(\n                'type'       => 'object',\n                'properties' => array(\n                    'seed'          => array( 'type' => 'string' ),\n                    'seed_analysis' => array( 'type' => 'object' ),\n                    'project_id'    => array( 'type' => 'integer' ),\n                    'query'         => array( 'type' => 'string' ),\n                    'brand_context' => array( 'type' => 'array' ),\n                ),\n                'required'   => array( 'seed' ),\n            ),\n            'output_schema'       => array(\n                'type'       => 'object',\n                'properties' => array(\n                    'cards'   => array( 'type' => 'array' ),\n                    'summary' => array( 'type' => 'string' ),\n                ),\n            ),\n            'execute_callback'    => __NAMESPACE__ . '\\execute',\n            'permission_callback' => function () {\n                return current_user_can( 'edit_posts' );\n            },\n            'meta'                => array(\n                'type'             => 'research',\n                'display_order'    => 50,\n                'show_in_rest'     => true,\n                'icon'             => 'search',\n                'thinking_message' => __( 'Searching {source}...', 'workflow-agent-{name}' ),\n                'success_message'  => __( '{Source} search complete.', 'workflow-agent-{name}' ),\n                \u002F\u002F Uncomment if the agent needs configuration:\n                \u002F\u002F 'settings_schema'  => array(\n                \u002F\u002F     'api_key' => array(\n                \u002F\u002F         'type'     => 'string',\n                \u002F\u002F         'label'    => 'API Key',\n                \u002F\u002F         'required' => true,\n                \u002F\u002F         'secret'   => true,\n                \u002F\u002F     ),\n                \u002F\u002F     'max_results' => array(\n                \u002F\u002F         'type'    => 'integer',\n                \u002F\u002F         'label'   => 'Max Results',\n                \u002F\u002F         'default' => 10,\n                \u002F\u002F         'minimum' => 1,\n                \u002F\u002F         'maximum' => 50,\n                \u002F\u002F     ),\n                \u002F\u002F ),\n                \u002F\u002F See the Availability section below for the callback body.\n                \u002F\u002F 'availability_callback' => __NAMESPACE__ . '\\check_availability',\n            ),\n        )\n    );\n}\n\n\u002F**\n * Execute the research search.\n *\n * When `query` is present (manual follow-up), search that term directly.\n * Otherwise use targeted search_queries from seed analysis, falling back\n * to the raw seed only if analysis produced nothing.\n *\n * @param array $input { seed: string, seed_analysis: array, query?: string, brand_context?: array }\n * @return array { cards: array, summary: string }\n *\u002F\nfunction execute( array $input ): array {\n    $seed_analysis = $input['seed_analysis'] ?? array();\n\n    if ( ! empty( $input['query'] ) ) {\n        $queries = array( $input['query'] );\n    } else {\n        $queries = $seed_analysis['search_queries'] ?? array();\n        if ( empty( $queries ) ) {\n            $queries = array( $input['seed'] ?? '' );\n        }\n    }\n\n    $queries = array_filter( $queries );\n    if ( empty( $queries ) ) {\n        return array( 'cards' => array(), 'summary' => 'No search query provided.' );\n    }\n\n    $all_cards = array();\n    foreach ( array_slice( $queries, 0, 3 ) as $query ) {\n        $all_cards = array_merge( $all_cards, search_source( $query ) );\n    }\n\n    return array(\n        'cards'   => $all_cards,\n        'summary' => sprintf( 'Found %d results.', count( $all_cards ) ),\n    );\n}\n\nfunction search_source( string $query ): array {\n    $url      = add_query_arg( array( 'q' => $query ), 'https:\u002F\u002Fapi.example.com\u002Fsearch' );\n    $response = wp_remote_get( $url, array( 'timeout' => 10 ) );\n\n    if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {\n        return array();\n    }\n\n    $body    = json_decode( wp_remote_retrieve_body( $response ), true );\n    $results = $body['results'] ?? array();\n    $cards   = array();\n\n    foreach ( array_slice( $results, 0, 10 ) as $item ) {\n        $cards[] = array(\n            'type'        => 'article',\n            'source_type' => 'article',\n            'origin'      => '{name}',\n            'title'       => $item['title'] ?? '',\n            'url'         => $item['url'] ?? '',\n            'excerpt'     => $item['description'] ?? '',\n            'content'     => $item['body'] ?? '',\n            'domain'      => '{domain.com}',\n            'author'      => $item['author'] ?? null,\n            'date'        => $item['date'] ?? null,\n            'image'       => $item['image'] ?? null,\n            'source'      => '{name}',\n        );\n    }\n\n    return $cards;\n}\n```\n\n### Research Card Fields\n\nEvery card **must** include:\n- `source_type` — `'article'`, `'image'`, `'video'`, `'discussion'`, or `'document'`\n- `origin` — identifies where this card came from (your source name)\n- `title` — display title\n- `url` — link to the original source\n\nRecommended: `excerpt`, `content`, `domain`, `author`, `date`, `image`, `score`, `source`.\n\n**These fields are the card's identity.** A stored source's id is derived from\nthe card — the URL when it has one, otherwise `title` plus `content` — so\nreturning the same card on a later run updates nothing and inserts nothing\nrather than adding a duplicate. Two consequences for your agent:\n\n- Return a stable `url` for anything that has one. A URL that changes between\n  runs (a cache-busting query param, a session id) forks into a new card\n  each time.\n- If your agent generates content rather than finding it, put the full body in\n  `content`. Cards with no URL are identified by title plus body, so two\n  generated cards that differ only in a field you left out will collapse into\n  one and the second will be silently dropped.\n\nOptional grouping: if your agent returns related cards (e.g., an article + its comments), give them the same `group_id` string. The mood board will render them as a linked pair.\n\n## Boilerplate: Stage-Capable\n\nUse this when the agent only runs as an AI-owned workflow stage.\n\n```php\n\u003C?php\n\u002F**\n * Plugin Name: Workflow Agent: {Display Name}\n * Description: Stage-capable agent that {describes what it checks or rewrites}.\n * Version: 1.0.0\n * Requires Plugins: vip-workflows\n * Text Domain: workflow-agent-{name}\n *\n * @package WorkflowAgent{PascalName}\n *\u002F\n\ndeclare( strict_types=1 );\n\nnamespace WorkflowAgent{PascalName};\n\nuse VIPWorkflows\\Abilities\\Agents\\StageAgent;\n\nif ( ! defined( 'ABSPATH' ) ) {\n    exit;\n}\n\nadd_action( 'vip_workflows_register_abilities', __NAMESPACE__ . '\\register' );\nadd_action( 'vip_workflows_register_assistant_meta', __NAMESPACE__ . '\\register_agent_meta' );\n\nfunction register(): void {\n    if ( ! function_exists( 'vip_workflows_register_ability' ) || ! class_exists( StageAgent::class ) ) {\n        return;\n    }\n\n    vip_workflows_register_ability(\n        'workflow-agent-{name}\u002F{slug}',\n        array(\n            'label'               => __( '{Display Name}', 'workflow-agent-{name}' ),\n            'description'         => __( '{One-line description.}', 'workflow-agent-{name}' ),\n            'category'            => 'vip-workflows',\n            'input_schema'        => array(\n                'type'                 => 'object',\n                'additionalProperties' => false,\n                'properties'           => array(\n                    'post_id' => array(\n                        'type'        => 'integer',\n                        'description' => __( 'The post ID for this agent.', 'workflow-agent-{name}' ),\n                    ),\n                ),\n                'required'             => array( 'post_id' ),\n            ),\n            'output_schema'       => array(\n                'type'                 => 'object',\n                'additionalProperties' => false,\n                'required'             => array( 'status', 'summary' ),\n                'properties'           => array(\n                    'status'  => array(\n                        'type' => 'string',\n                        'enum' => array( 'pass', 'fail' ),\n                    ),\n                    'summary' => array( 'type' => 'string' ),\n                    'issues'  => array( 'type' => 'array' ),\n                ),\n            ),\n            'execute_callback'    => __NAMESPACE__ . '\\execute',\n            'permission_callback' => function () {\n                return current_user_can( 'edit_posts' );\n            },\n            'meta'                => array(\n                'type'                => 'agent',\n                'show_in_rest'        => true,\n                'show_in_commands'    => false,\n                'transition_eligible' => false,\n                'icon'                => 'search',\n                'supports'            => array( 'workflow', 'stage' ),\n                'stage_eligible'      => true,\n                'annotations'         => array(\n                    'readonly'    => true,\n                    'destructive' => false,\n                    'idempotent'  => true,\n                ),\n            ),\n        )\n    );\n}\n\nfunction register_agent_meta( $registry ): void {\n    $registry->register(\n        'workflow-agent-{name}',\n        array(\n            'label'        => __( '{Display Name}', 'workflow-agent-{name}' ),\n            'description'  => __( '{One-line description.}', 'workflow-agent-{name}' ),\n            'icon'         => 'search',\n            'ability_ids'  => array( 'workflow-agent-{name}\u002F{slug}' ),\n            'capabilities' => array( 'stage' ),\n        )\n    );\n}\n\nfunction execute( ?array $input = null ) {\n    $input   = $input ?? array();\n    $post_id = (int) ( $input['post_id'] ?? 0 );\n\n    if ( ! $post_id ) {\n        return new \\WP_Error( 'missing_post_id', __( 'A post_id is required.', 'workflow-agent-{name}' ) );\n    }\n\n    $post = StageAgent::read_post( $post_id );\n    if ( is_wp_error( $post ) ) {\n        return $post;\n    }\n\n    \u002F\u002F Build your prompt or deterministic check from $post['title'] and $post['content'].\n    \u002F\u002F Return StageAgent::result( 'pass', '...' ) or StageAgent::result( 'fail', '...', array( 'issues' => $issues ) ).\n}\n```\n\nThe unified agent REST entry will include `capabilities: [ 'stage' ]` and `available_in_ai_stage: true` when the ability is registered and stage-eligible.\n\n## Boilerplate: Discovery-Only\n\nUse this when the agent only surfaces prompts on the landing page.\n\n```php\n\u003C?php\n\u002F**\n * Plugin Name: Workflow Discovery: {Display Name}\n * Description: Story discovery provider that surfaces prompts from {data source}.\n * Version: 1.0.0\n * Requires Plugins: vip-workflows\n * Text Domain: workflow-discovery-{name}\n *\n * @package WorkflowDiscovery{PascalName}\n *\u002F\n\ndeclare( strict_types=1 );\n\nnamespace WorkflowDiscovery{PascalName};\n\nif ( ! defined( 'ABSPATH' ) ) {\n    exit;\n}\n\nadd_action( 'vip_workflows_register_discovery_providers', __NAMESPACE__ . '\\register' );\n\nfunction register( $registry ): void {\n    $registry->register( '{provider-slug}', array(\n        'label'       => __( '{Display Name}', 'workflow-discovery-{name}' ),\n        'description' => __( '{One-line description of what this provider surfaces.}', 'workflow-discovery-{name}' ),\n        'icon'        => 'search',\n        'features'    => array( 'recommend', 'search' ), \u002F\u002F keep only what you implement\n        'callbacks'   => array(\n            'recommend' => __NAMESPACE__ . '\\get_recommendations', \u002F\u002F required if 'recommend' in features\n            'search'    => __NAMESPACE__ . '\\search',              \u002F\u002F required if 'search' in features\n            'filters'   => __NAMESPACE__ . '\\get_filters',         \u002F\u002F required if 'search' in features\n            'seed'      => __NAMESPACE__ . '\\generate_seed',       \u002F\u002F always required\n        ),\n        \u002F\u002F Uncomment if credentials are needed. See the Availability section below\n        \u002F\u002F for the callback body.\n        \u002F\u002F 'availability_callback' => __NAMESPACE__ . '\\check_availability',\n    ) );\n}\n\n\u002F**\n * Return curated prompts for the landing page.\n *\n * Called on page load with the provider's saved settings.\n * Return up to 6 prompts. Cache aggressively (see Caching section).\n *\n * @param array $config Provider settings (categories, regions, etc.).\n * @return array Array of story prompt arrays.\n *\u002F\nfunction get_recommendations( array $config ): array {\n    $response = wp_remote_get( 'https:\u002F\u002Fapi.example.com\u002Fupcoming', array( 'timeout' => 10 ) );\n\n    if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {\n        return array();\n    }\n\n    $body    = json_decode( wp_remote_retrieve_body( $response ), true );\n    $results = $body['items'] ?? array();\n\n    return array_map( __NAMESPACE__ . '\\normalize_prompt', array_slice( $results, 0, 6 ) );\n}\n\n\u002F**\n * Search for prompts matching user criteria.\n *\n * @param array $params { text: string, filters: array\u003Cstring, mixed> }\n * @return array Array of story prompt arrays.\n *\u002F\nfunction search( array $params ): array {\n    $text    = $params['text'] ?? '';\n    $filters = $params['filters'] ?? array();\n\n    $url      = add_query_arg( array( 'q' => $text ), 'https:\u002F\u002Fapi.example.com\u002Fsearch' );\n    $response = wp_remote_get( $url, array( 'timeout' => 10 ) );\n\n    if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {\n        return array();\n    }\n\n    $body    = json_decode( wp_remote_retrieve_body( $response ), true );\n    $results = $body['items'] ?? array();\n\n    return array_map( __NAMESPACE__ . '\\normalize_prompt', $results );\n}\n\n\u002F**\n * Return search filter definitions for the modal UI.\n *\n * Supported types: 'select', 'multi_select', 'date_range'.\n * Return an empty array if the provider has no filters but supports search.\n *\u002F\nfunction get_filters(): array {\n    return array(\n        array(\n            'key'     => 'category',\n            'label'   => __( 'Category', 'workflow-discovery-{name}' ),\n            'type'    => 'select',\n            'options' => array(\n                array( 'value' => 'all', 'label' => 'All categories' ),\n            ),\n        ),\n        \u002F\u002F array(\n        \u002F\u002F     'key'     => 'date_range',\n        \u002F\u002F     'label'   => __( 'Date range', 'workflow-discovery-{name}' ),\n        \u002F\u002F     'type'    => 'date_range',\n        \u002F\u002F     'default' => array( 'from' => 'today', 'to' => '+90 days' ),\n        \u002F\u002F ),\n    );\n}\n\n\u002F**\n * Compose a seed string from a selected prompt.\n *\n * Called when an editor clicks a prompt card. The returned string becomes\n * the seed for a new ideation project. Include the most relevant context\n * your data source provides.\n *\u002F\nfunction generate_seed( array $prompt ): string {\n    $parts = array( $prompt['title'] );\n\n    if ( ! empty( $prompt['description'] ) ) {\n        $parts[] = $prompt['description'];\n    }\n    if ( ! empty( $prompt['date'] ) ) {\n        $parts[] = sprintf( 'Scheduled for %s.', date( 'F j, Y', strtotime( $prompt['date'] ) ) );\n    }\n    if ( ! empty( $prompt['tags'] ) ) {\n        $parts[] = sprintf( 'Topics: %s.', implode( ', ', $prompt['tags'] ) );\n    }\n\n    return implode( ' ', $parts );\n}\n\nfunction normalize_prompt( array $item ): array {\n    return array(\n        'id'          => '{provider-slug}-' . ( $item['id'] ?? '' ),\n        'provider'    => '{provider-slug}',\n        'title'       => $item['title'] ?? '',\n        'description' => $item['description'] ?? '',\n        'url'         => $item['url'] ?? '',\n        'date'        => $item['date'] ?? null,\n        'date_end'    => $item['date_end'] ?? null,\n        'tags'        => $item['tags'] ?? array(),\n        'importance'  => $item['importance'] ?? 'normal',\n        'meta'        => $item['meta'] ?? array(),\n    );\n}\n```\n\n### Story Prompt Shape\n\nEvery prompt **must** include:\n- `id` — provider-namespaced unique identifier (e.g., `foresight-703721`)\n- `provider` — the provider slug\n- `title` — display title\n\nRecommended: `description`, `url`, `date`, `date_end`, `tags`, `importance`, `meta`.\n\n`importance` is provider-defined. The UI renders badges based on it (`key_event`, `top_story`, `normal`) but does not enforce a universal scale. `meta` is freeform and provider-specific — use it for structured data your seed generation or settings UI needs (event types, regions, contacts, embargo info, etc.).\n\n## Boilerplate: Research + Discovery\n\nUse this when one plugin provides both capabilities (e.g., Qwoted surfaces journalist requests as prompts *and* finds expert sources during research).\n\nRegister both independently, then declare a unified agent manifest so the Agents tab renders a single card covering both with a shared label, icon, description, and settings form.\n\n```php\n\u003C?php\n\u002F**\n * Plugin Name: Workflow {Display Name}\n * Description: {Short description combining both capabilities.}\n * Version: 1.0.0\n * Requires Plugins: vip-workflows\n * Text Domain: workflow-{name}\n *\n * @package Workflow{PascalName}\n *\u002F\n\ndeclare( strict_types=1 );\n\nnamespace Workflow{PascalName};\n\nif ( ! defined( 'ABSPATH' ) ) {\n    exit;\n}\n\n\u002F\u002F Register the research ability.\nadd_action( 'wp_abilities_api_init', __NAMESPACE__ . '\\register_ability' );\n\nfunction register_ability(): void {\n    if ( ! function_exists( 'vip_workflows_register_ability' ) ) {\n        return;\n    }\n\n    vip_workflows_register_ability(\n        'workflow-{name}\u002F{ability-slug}',\n        array(\n            'label'               => __( '{Display Name}', 'workflow-{name}' ),\n            'description'         => __( '{Research description.}', 'workflow-{name}' ),\n            'category'            => 'research',\n            \u002F\u002F ... input_schema, output_schema, execute_callback, permission_callback\n            'meta'                => array(\n                'type'         => 'research',\n                'show_in_rest' => true,\n                'icon'         => 'search',\n            ),\n        )\n    );\n}\n\n\u002F\u002F Register the discovery provider.\nadd_action( 'vip_workflows_register_discovery_providers', __NAMESPACE__ . '\\register_provider' );\n\nfunction register_provider( $registry ): void {\n    $registry->register( '{provider-slug}', array(\n        'label'     => __( '{Display Name}', 'workflow-{name}' ),\n        'icon'      => 'search',\n        'features'  => array( 'recommend', 'search' ),\n        'callbacks' => array(\n            'recommend' => __NAMESPACE__ . '\\get_recommendations',\n            'search'    => __NAMESPACE__ . '\\search_prompts',\n            'filters'   => __NAMESPACE__ . '\\get_filters',\n            'seed'      => __NAMESPACE__ . '\\generate_seed',\n        ),\n    ) );\n}\n\n\u002F\u002F Declare the unified manifest so both appear as a single card.\nadd_action( 'vip_workflows_register_assistant_meta', __NAMESPACE__ . '\\register_assistant_meta' );\n\nfunction register_assistant_meta( $registry ): void {\n    $registry->register( 'workflow-{name}', array(\n        'label'           => __( '{Display Name}', 'workflow-{name}' ),\n        'description'     => __( 'Expert sources and story prompts from {source}.', 'workflow-{name}' ),\n        'icon'            => 'search',\n        'ability_ids'     => array( 'workflow-{name}\u002F{ability-slug}' ),\n        'provider_slugs'  => array( '{provider-slug}' ),\n        'settings_schema' => array(\n            'api_key' => array(\n                'type'     => 'string',\n                'label'    => 'API Key',\n                'required' => true,\n                'secret'   => true,\n            ),\n        ),\n    ) );\n}\n```\n\nWithout a manifest, the two registrations would show up as two separate cards. The manifest is only needed when one plugin spans both capabilities. Single-capability plugins are auto-detected and need no manifest.\n\n## Availability\n\nAn agent that needs configuration declares an `availability_callback` — in `meta` for an ability, as a top-level key for a discovery provider. Write it against the structured shape from the start: returning a bare `false` gets the card a generic \"required settings are not configured\" line that names nothing and links nowhere.\n\n**Return either:**\n\n| Return value | Meaning |\n|---|---|\n| `true` | Dependencies are met. Return this the moment they are — including when only one member of an `any` group is satisfied. |\n| `VIPWorkflows\\Abilities\\Availability::unmet( ... )` | Dependencies are not met, carrying the unmet requirements. |\n| `false` | Legacy shape. Still supported and silent, but the card can only render the generic line. |\n\n**The callback owns satisfaction.** It is the only code with credential access, so nothing downstream re-derives it: a requirement group contains *only* unmet members, and `Availability::unmet()` is never returned for a dependency that is actually satisfied.\n\n**Build requirements with `RequirementFactory`**, not by hand. Hand-construction means supplying an id, a kind, two message registers, source attribution, and a destination; the factory derives all of it, and resolves the destination against the install rather than hardcoding a screen that may not exist. Construct a `Requirement` directly only when no factory fits — for example a key read from your own `wp-config.php` constant, which needs `Destination::none()` naming that constant.\n\n| Factory method | Use when |\n|---|---|\n| `in_card( $id, $admin_reason, $user_message, $hint, $sources )` | The key is entered in the agent's own card fields (`settings_schema`). This is the usual case for a third-party agent. |\n| `missing_credential( $service, $service_label, $sources )` | The key is one the plugin reads through `VIPWorkflows\\AI\\Credentials`. Derives everything from the service slug, and resolves to Settings → Connectors or to the `wp-config.php` constant name depending on the install. |\n| `dependency( $id, $admin_reason, $user_message, $sources )` | A prerequisite other than a credential is missing (e.g. no provider is registered). |\n| `unsupported_environment( $id, $admin_reason, $user_message, $sources )` | The environment cannot support the capability, so there is nothing to configure. |\n\nGroup members with `RequirementGroup::all()` when every one is needed, or `RequirementGroup::any()` when one is enough — an `any` group renders as a single \"configure at least one of\" block rather than N separate blockers.\n\n```php\nuse VIPWorkflows\\Abilities\\Availability;\nuse VIPWorkflows\\Abilities\\RequirementFactory;\nuse VIPWorkflows\\Abilities\\RequirementGroup;\n\n\u002F**\n * Whether this agent's dependencies are met, and what is missing if not.\n *\n * Registered as the `availability_callback` for both the ability and the\n * discovery provider. Sharing one callback means both contribute the same\n * requirement id, so the card renders one row listing both capabilities.\n *\u002F\nfunction check_availability(): bool|Availability {\n    if ( is_configured() ) {\n        return true;\n    }\n\n    return Availability::unmet(\n        RequirementGroup::all(\n            RequirementFactory::in_card(\n                'settings:workflow-{name}',\n                __( '{Display Name} sign-in details are missing. Add the API key below.', 'workflow-{name}' ),\n                __( '{Display Name} is not connected. Ask an administrator to connect it.', 'workflow-{name}' ),\n                __( 'Complete the API key field below.', 'workflow-{name}' ),\n                array( __( '{Display Name}', 'workflow-{name}' ) )\n            )\n        )\n    );\n}\n\nfunction is_configured(): bool {\n    $settings = \\VIPWorkflows\\Abilities\\AbilitySettings::get_instance();\n    $options  = $settings->get_options( 'workflow-agent-{name}\u002F{slug}' );\n\n    return ! empty( $options['api_key'] );\n}\n```\n\n**Two message registers, and you must supply both.** Agent execution is gated on `edit_posts`, while the Agents screen and Settings → Connectors both require `manage_options`. The `$admin_reason` may name a screen; the `$user_message` must not — it is what an editor sees mid-workflow, and pointing them at a page they cannot open is a dead instruction. Which register is emitted is decided at the read boundary, not by you.\n\nNote the separation the Agents card preserves: **enabled** is an admin preference, **available** is whether dependencies are satisfied. Returning `false` from `availability_callback` does not disable an agent, and an admin disabling an agent does not make it unavailable.\n\n## Settings UI (Optional)\n\nIf the agent needs configuration, there are two paths:\n\n**Schema-based (recommended).** Declare `settings_schema` — in the ability `meta` for research-only, in the provider config for discovery-only, or in the unified manifest for both. The Agents tab auto-renders the form via `SchemaSettings`. No JS needed.\n\n**Fully custom React UI.** Inject a component via the unified JS filter:\n\n```javascript\nimport { addFilter } from '@wordpress\u002Fhooks';\n\naddFilter(\n    'vipWorkflows.assistantSettings',\n    'workflow-{name}',\n    ( component, assistant, { disabled, onHasChangesChange, onSaveRef } ) => {\n        \u002F\u002F Match on your ability id, not on `assistant.slug`. An entry slug is\n        \u002F\u002F derived, and only a manifest controls its own: an agent with no\n        \u002F\u002F manifest gets a slug built from its whole ability id\n        \u002F\u002F (`workflow-{name}-{slug}`), so a slug comparison silently stops\n        \u002F\u002F matching. Ability ids are yours and never change under you.\n        if ( ! assistant.ability_ids?.includes( 'workflow-{name}\u002F{slug}' ) ) {\n            return component;\n        }\n\n        return (\n            \u003CSettingsForm\n                assistant={ assistant }\n                disabled={ disabled }\n                onHasChangesChange={ onHasChangesChange }\n                onSaveRef={ onSaveRef }\n            \u002F>\n        );\n    }\n);\n```\n\nThe filter receives the full unified agent entry (`slug`, `capabilities`, `ability_ids`, `provider_slugs`, `options`, `settings_schema`, …) plus a callbacks object. The card always passes that object, on every path, so destructure it directly — it is never `undefined`. It carries three members:\n\n- `disabled` (`bool`) — the agent is switched off.\n- `onHasChangesChange( bool )` — drives the Save button's enabled state.\n- `onSaveRef( fn )` — registers a handler invoked when the user clicks Save.\n\n**You must honor `disabled`.** Everything your component renders describes how the agent behaves when it runs, so a switched-off agent offers none of it: pass `disabled` to every control, and never report `true` through `onHasChangesChange` while it is set. The card can only switch off the controls it renders itself, and your component replaces those outright — a component that ignores the flag lets a reader configure and save an agent that never runs, which is exactly the bug the flag exists to close. The Enabled toggle stays live; it is the way back.\n\nSettings persist via `POST \u002Fvip-workflows\u002Fv1\u002Fassistants\u002F{slug}\u002Fsettings` with `{ enabled?: bool, options?: object }`. The registry writes through to the underlying legacy options (`vip_workflows_ability_settings[ability_id]`, `vip_discovery_provider_settings`, `vip_discovery_provider_{slug}`), so existing consumers keep working unchanged.\n\nThe legacy `vipWorkflows.assistantSettingsComponent` (research) and `vip_workflows_discovery_provider_settings` (discovery) filters are still honored for backward compatibility, but new code should always use `vipWorkflows.assistantSettings`. Both carry the same obligation: the legacy assistants filter receives the same three-member callbacks object, and the legacy discovery filter returns a component *type* that the card renders with a `disabled` prop alongside `providerSlug`.\n\n## Caching\n\nCache external API responses server-side using WordPress transients:\n\n- Research search results: 5–15 min TTL (keyed by query)\n- Discovery recommendations: 15–30 min TTL\n- Discovery search results: 5–10 min TTL (keyed by query + filters hash)\n- Filter definitions: 24 hour TTL (taxonomy data changes rarely)\n- Auth tokens: cache until expiry minus a buffer\n\n## Registration Rules\n\n**Research ability:**\n- Ability name **must** be namespaced: `plugin-slug\u002Fability-slug`\n- `category` must be `'research'`\n- `meta.type` must be `'research'`\n- `meta.show_in_rest` must be `true`\n- Hook into `wp_abilities_api_init` (not `init`)\n- Guard with `function_exists( 'vip_workflows_register_ability' )` so the plugin degrades gracefully\n\n**Discovery provider:**\n- Provider slug must be unique across all plugins\n- `features` must contain `'recommend'` and\u002For `'search'`\n- If `recommend` is declared, the `recommend` callback must be callable\n- If `search` is declared, both `search` and `filters` callbacks must be callable\n- The `seed` callback is always required\n- Hook into `vip_workflows_register_discovery_providers` (receives the registry instance)\n- `availability_callback` is optional; if omitted the provider is always considered available. When present it should return `true` or an `Availability` — see [Availability](#availability)\n\n**Unified manifest (multi-capability plugins):**\n- `slug` must match the plugin's directory\u002Ftext-domain slug\n- `ability_ids` must reference abilities the plugin actually registers\n- `provider_slugs` must reference providers the plugin actually registers\n- `capabilities` may include `'stage'` when the plugin has at least one registered stage-eligible ability; the registry ignores unsupported manifest claims\n- Hook into `vip_workflows_register_assistant_meta` (receives the registry instance)\n\n**Stage ability:**\n- Ability name **must** be namespaced: `plugin-slug\u002Fability-slug`\n- `category` should be `'vip-workflows'`\n- `meta.type` must be `'agent'`\n- `meta.supports` must include both `'workflow'` and `'stage'`\n- `meta.stage_eligible` must be `true`\n- `input_schema` must require `post_id`\n- `output_schema` must require `status` and `summary`, with `status` limited to `pass` and `fail`\n- Hook into `vip_workflows_register_abilities` so core stage helpers are already loaded\n- Register a manifest on `vip_workflows_register_assistant_meta` with `capabilities => array( 'stage' )` so the Agents card is marked available in AI stages when the ability metadata also qualifies\n- Read-only agents should declare `annotations.readonly => true`; mutating agents must write through `StageAgent::write_content()` (rewrite the body) or `StageAgent::write_block_notes()` (attach native block notes), and declare `annotations.readonly => false`\n\n## Testing\n\n1. Place the plugin directory alongside `vip-workflows\u002F`.\n2. Activate it in WordPress admin.\n3. Go to **Integrations > Agents** to verify it appears as a single card and can be enabled.\n4. Configure any settings, then:\n   - **Research:** Create a new ideation project and confirm the agent runs on the mood board.\n   - **Stage:** Open a Sequence, select a stage node, and confirm the agent appears in the inspector's Agent picker; choosing it turns the node purple and gives it the three outcome handles.\n   - **Stage:** Drag each outcome handle onto a destination stage, then save and reload the Sequence to confirm `agent.ability_id`, `agent.settings`, and `agent.routing` persist.\n   - **Stage:** Transition a post into the AI-owned stage and confirm the runner stores the result and routes by `pass`, `fail`, or `error`.\n   - **Discovery (recommend):** Visit the Ideation landing page and confirm curated prompts appear.\n   - **Discovery (search):** Click \"Browse more…\" to open the search modal and test queries + filters.\n   - **Discovery (prompt selection):** Click a prompt and confirm a new project is created with the expected seed text.\n",{"data":36,"body":37},{"name":4,"description":6},{"type":38,"children":39},"root",[40,49,70,119,133,140,145,338,351,387,406,412,424,429,727,774,800,818,827,869,875,880,1168,1174,1186,1199,1204,1281,1287,1292,2645,2652,2664,2745,2806,2830,2857,2870,2876,2881,3707,3727,3733,3738,4869,4875,4885,4926,4977,5016,5022,5034,5039,5647,5652,5657,5684,5692,5772,5797,5837,5948,5976,6251,6293,6326,6332,6337,6369,6379,6868,6922,6965,7003,7045,7094,7100,7105,7133,7139,7147,7246,7254,7379,7387,7447,7455,7656,7662,7808],{"type":41,"tag":42,"props":43,"children":45},"element","h1",{"id":44},"create-a-vip-workflows-agent",[46],{"type":47,"value":48},"text","Create a VIP Workflows Agent",{"type":41,"tag":50,"props":51,"children":52},"p",{},[53,55,61,63,68],{"type":47,"value":54},"An ",{"type":41,"tag":56,"props":57,"children":58},"strong",{},[59],{"type":47,"value":60},"agent",{"type":47,"value":62}," is a standalone WordPress plugin that extends VIP Workflows. All agents appear as cards on the unified ",{"type":41,"tag":56,"props":64,"children":65},{},[66],{"type":47,"value":67},"Integrations > Agents",{"type":47,"value":69}," tab. An agent can provide one or more of these capabilities:",{"type":41,"tag":71,"props":72,"children":73},"ul",{},[74,93,109],{"type":41,"tag":75,"props":76,"children":77},"li",{},[78,83,85,91],{"type":41,"tag":56,"props":79,"children":80},{},[81],{"type":47,"value":82},"Research",{"type":47,"value":84}," — runs ",{"type":41,"tag":86,"props":87,"children":88},"em",{},[89],{"type":47,"value":90},"after",{"type":47,"value":92}," an editor has a seed, inside an ideation project. Returns cards (articles, discussions, media) that populate the project's mood board.",{"type":41,"tag":75,"props":94,"children":95},{},[96,101,102,107],{"type":41,"tag":56,"props":97,"children":98},{},[99],{"type":47,"value":100},"Discovery",{"type":47,"value":84},{"type":41,"tag":86,"props":103,"children":104},{},[105],{"type":47,"value":106},"before",{"type":47,"value":108}," an editor has a seed, on the ideation landing page. Returns story prompts that editors can click to spawn a new project.",{"type":41,"tag":75,"props":110,"children":111},{},[112,117],{"type":41,"tag":56,"props":113,"children":114},{},[115],{"type":47,"value":116},"Stage",{"type":47,"value":118}," — runs when a post enters an AI-owned workflow stage. Returns a pass\u002Ffail verdict the stage's routing map turns into an exit transition; execution errors follow the stage's optional error route or fail in place.",{"type":41,"tag":50,"props":120,"children":121},{},[122,124,131],{"type":47,"value":123},"A single plugin can provide research only, discovery only, stage only, or a combination. See ",{"type":41,"tag":125,"props":126,"children":128},"code",{"className":127},[],[129],{"type":47,"value":130},"docs\u002Fspecs\u002Fshipped\u002Funified-assistants-tab.md",{"type":47,"value":132}," for the underlying architecture.",{"type":41,"tag":134,"props":135,"children":137},"h2",{"id":136},"decide-the-shape-first",[138],{"type":47,"value":139},"Decide the Shape First",{"type":41,"tag":50,"props":141,"children":142},{},[143],{"type":47,"value":144},"Before writing any code, decide which capabilities the agent offers:",{"type":41,"tag":146,"props":147,"children":148},"table",{},[149,183],{"type":41,"tag":150,"props":151,"children":152},"thead",{},[153],{"type":41,"tag":154,"props":155,"children":156},"tr",{},[157,163,168,173,178],{"type":41,"tag":158,"props":159,"children":160},"th",{},[161],{"type":47,"value":162},"Capability",{"type":41,"tag":158,"props":164,"children":165},{},[166],{"type":47,"value":167},"When it runs",{"type":41,"tag":158,"props":169,"children":170},{},[171],{"type":47,"value":172},"Returns",{"type":41,"tag":158,"props":174,"children":175},{},[176],{"type":47,"value":177},"Registration hook",{"type":41,"tag":158,"props":179,"children":180},{},[181],{"type":47,"value":182},"Required callbacks",{"type":41,"tag":184,"props":185,"children":186},"tbody",{},[187,226,297],{"type":41,"tag":154,"props":188,"children":189},{},[190,198,203,208,217],{"type":41,"tag":191,"props":192,"children":193},"td",{},[194],{"type":41,"tag":56,"props":195,"children":196},{},[197],{"type":47,"value":82},{"type":41,"tag":191,"props":199,"children":200},{},[201],{"type":47,"value":202},"Inside a project (after seed)",{"type":41,"tag":191,"props":204,"children":205},{},[206],{"type":47,"value":207},"Cards for mood board",{"type":41,"tag":191,"props":209,"children":210},{},[211],{"type":41,"tag":125,"props":212,"children":214},{"className":213},[],[215],{"type":47,"value":216},"wp_abilities_api_init",{"type":41,"tag":191,"props":218,"children":219},{},[220],{"type":41,"tag":125,"props":221,"children":223},{"className":222},[],[224],{"type":47,"value":225},"execute_callback",{"type":41,"tag":154,"props":227,"children":228},{},[229,236,241,246,255],{"type":41,"tag":191,"props":230,"children":231},{},[232],{"type":41,"tag":56,"props":233,"children":234},{},[235],{"type":47,"value":100},{"type":41,"tag":191,"props":237,"children":238},{},[239],{"type":47,"value":240},"Landing page (before seed)",{"type":41,"tag":191,"props":242,"children":243},{},[244],{"type":47,"value":245},"Story prompts",{"type":41,"tag":191,"props":247,"children":248},{},[249],{"type":41,"tag":125,"props":250,"children":252},{"className":251},[],[253],{"type":47,"value":254},"vip_workflows_register_discovery_providers",{"type":41,"tag":191,"props":256,"children":257},{},[258,264,266,272,274,280,282,288,290,295],{"type":41,"tag":125,"props":259,"children":261},{"className":260},[],[262],{"type":47,"value":263},"seed",{"type":47,"value":265}," + one or both of ",{"type":41,"tag":125,"props":267,"children":269},{"className":268},[],[270],{"type":47,"value":271},"recommend",{"type":47,"value":273}," \u002F ",{"type":41,"tag":125,"props":275,"children":277},{"className":276},[],[278],{"type":47,"value":279},"search",{"type":47,"value":281}," (+ ",{"type":41,"tag":125,"props":283,"children":285},{"className":284},[],[286],{"type":47,"value":287},"filters",{"type":47,"value":289}," if ",{"type":41,"tag":125,"props":291,"children":293},{"className":292},[],[294],{"type":47,"value":279},{"type":47,"value":296},")",{"type":41,"tag":154,"props":298,"children":299},{},[300,307,312,321,330],{"type":41,"tag":191,"props":301,"children":302},{},[303],{"type":41,"tag":56,"props":304,"children":305},{},[306],{"type":47,"value":116},{"type":41,"tag":191,"props":308,"children":309},{},[310],{"type":47,"value":311},"When a post enters an AI-owned workflow stage",{"type":41,"tag":191,"props":313,"children":314},{},[315],{"type":41,"tag":125,"props":316,"children":318},{"className":317},[],[319],{"type":47,"value":320},"{ status: pass|fail, summary }",{"type":41,"tag":191,"props":322,"children":323},{},[324],{"type":41,"tag":125,"props":325,"children":327},{"className":326},[],[328],{"type":47,"value":329},"vip_workflows_register_abilities",{"type":41,"tag":191,"props":331,"children":332},{},[333],{"type":41,"tag":125,"props":334,"children":336},{"className":335},[],[337],{"type":47,"value":225},{"type":41,"tag":50,"props":339,"children":340},{},[341,343,349],{"type":47,"value":342},"Discovery itself has two independent sub-features declared in the ",{"type":41,"tag":125,"props":344,"children":346},{"className":345},[],[347],{"type":47,"value":348},"features",{"type":47,"value":350}," array:",{"type":41,"tag":71,"props":352,"children":353},{},[354,367],{"type":41,"tag":75,"props":355,"children":356},{},[357,365],{"type":41,"tag":56,"props":358,"children":359},{},[360],{"type":41,"tag":125,"props":361,"children":363},{"className":362},[],[364],{"type":47,"value":271},{"type":47,"value":366}," — returns a curated list for the landing page. Called on page load, no user query. Think \"what's newsworthy right now.\"",{"type":41,"tag":75,"props":368,"children":369},{},[370,378,380,385],{"type":41,"tag":56,"props":371,"children":372},{},[373],{"type":41,"tag":125,"props":374,"children":376},{"className":375},[],[377],{"type":47,"value":279},{"type":47,"value":379}," — returns results matching a user query and filter selections, powering the \"Browse more…\" modal. Requires ",{"type":41,"tag":125,"props":381,"children":383},{"className":382},[],[384],{"type":47,"value":287},{"type":47,"value":386}," callback alongside.",{"type":41,"tag":50,"props":388,"children":389},{},[390,392,397,399,404],{"type":47,"value":391},"A discovery provider can declare ",{"type":41,"tag":125,"props":393,"children":395},{"className":394},[],[396],{"type":47,"value":271},{"type":47,"value":398}," only, ",{"type":41,"tag":125,"props":400,"children":402},{"className":401},[],[403],{"type":47,"value":279},{"type":47,"value":405}," only, or both. Most full-featured sources do both.",{"type":41,"tag":134,"props":407,"children":409},{"id":408},"stage-agents-ai-owned-workflow-stages",[410],{"type":47,"value":411},"Stage Agents (AI-owned workflow stages)",{"type":41,"tag":50,"props":413,"children":414},{},[415,417,422],{"type":47,"value":416},"A ",{"type":41,"tag":56,"props":418,"children":419},{},[420],{"type":47,"value":421},"stage agent",{"type":47,"value":423}," runs automatically when a post enters a workflow stage that has been marked as AI-owned. It inspects the post, optionally rewrites the content (saving a revision), and returns an outcome. The stage's routing table then maps that outcome to one of the stage's configured transitions — so the agent participates in transitions exactly like a human stage (bump back, advance to a human, or move on).",{"type":41,"tag":50,"props":425,"children":426},{},[427],{"type":47,"value":428},"A stage agent is a normal ability plus an agent manifest. It has different requirements from research and discovery agents:",{"type":41,"tag":430,"props":431,"children":432},"ol",{},[433,459,509,542,630],{"type":41,"tag":75,"props":434,"children":435},{},[436,441,443,449,451,457],{"type":41,"tag":56,"props":437,"children":438},{},[439],{"type":47,"value":440},"Input contract",{"type":47,"value":442}," — take ",{"type":41,"tag":125,"props":444,"children":446},{"className":445},[],[447],{"type":47,"value":448},"post_id",{"type":47,"value":450},"; read the post through ",{"type":41,"tag":125,"props":452,"children":454},{"className":453},[],[455],{"type":47,"value":456},"VIPWorkflows\\Abilities\\Agents\\StageAgent::read_post()",{"type":47,"value":458}," so permissions and empty-content errors match core stage agents.",{"type":41,"tag":75,"props":460,"children":461},{},[462,467,469,475,477,483,485,491,493,499,501,507],{"type":41,"tag":56,"props":463,"children":464},{},[465],{"type":47,"value":466},"Stage metadata",{"type":47,"value":468}," — set ",{"type":41,"tag":125,"props":470,"children":472},{"className":471},[],[473],{"type":47,"value":474},"meta.stage_eligible => true",{"type":47,"value":476}," and include ",{"type":41,"tag":125,"props":478,"children":480},{"className":479},[],[481],{"type":47,"value":482},"'stage'",{"type":47,"value":484}," in ",{"type":41,"tag":125,"props":486,"children":488},{"className":487},[],[489],{"type":47,"value":490},"meta.supports",{"type":47,"value":492}," alongside ",{"type":41,"tag":125,"props":494,"children":496},{"className":495},[],[497],{"type":47,"value":498},"'workflow'",{"type":47,"value":500},". The Sequence editor's agent picker and ",{"type":41,"tag":125,"props":502,"children":504},{"className":503},[],[505],{"type":47,"value":506},"\u002Fvip-workflows\u002Fv1\u002Fabilities?context=stage",{"type":47,"value":508}," only list abilities with both signals.",{"type":41,"tag":75,"props":510,"children":511},{},[512,517,519,525,527,533,535,540],{"type":41,"tag":56,"props":513,"children":514},{},[515],{"type":47,"value":516},"Agent manifest",{"type":47,"value":518}," — register on ",{"type":41,"tag":125,"props":520,"children":522},{"className":521},[],[523],{"type":47,"value":524},"vip_workflows_register_assistant_meta",{"type":47,"value":526}," with ",{"type":41,"tag":125,"props":528,"children":530},{"className":529},[],[531],{"type":47,"value":532},"capabilities => array( 'stage' )",{"type":47,"value":534},". This marks the card as ",{"type":41,"tag":56,"props":536,"children":537},{},[538],{"type":47,"value":539},"Available in AI stage",{"type":47,"value":541}," only when the referenced ability is also stage-eligible.",{"type":41,"tag":75,"props":543,"children":544},{},[545,550,552,558,560,566,568,574,576,582,584,589,591,596,598,604,606,612,614,620,622,628],{"type":41,"tag":56,"props":546,"children":547},{},[548],{"type":47,"value":549},"Output contract",{"type":47,"value":551}," — return ",{"type":41,"tag":125,"props":553,"children":555},{"className":554},[],[556],{"type":47,"value":557},"{ status, summary, ... }",{"type":47,"value":559}," where ",{"type":41,"tag":125,"props":561,"children":563},{"className":562},[],[564],{"type":47,"value":565},"status",{"type":47,"value":567}," is either ",{"type":41,"tag":125,"props":569,"children":571},{"className":570},[],[572],{"type":47,"value":573},"pass",{"type":47,"value":575}," or ",{"type":41,"tag":125,"props":577,"children":579},{"className":578},[],[580],{"type":47,"value":581},"fail",{"type":47,"value":583},". Stage agents make a binary editorial judgment: return ",{"type":41,"tag":125,"props":585,"children":587},{"className":586},[],[588],{"type":47,"value":573},{"type":47,"value":590}," when the post is safe to continue on the success path, or ",{"type":41,"tag":125,"props":592,"children":594},{"className":593},[],[595],{"type":47,"value":581},{"type":47,"value":597}," (with a clear ",{"type":41,"tag":125,"props":599,"children":601},{"className":600},[],[602],{"type":47,"value":603},"summary",{"type":47,"value":605},"\u002F",{"type":41,"tag":125,"props":607,"children":609},{"className":608},[],[610],{"type":47,"value":611},"issues",{"type":47,"value":613}," payload) when it should not. Return a ",{"type":41,"tag":125,"props":615,"children":617},{"className":616},[],[618],{"type":47,"value":619},"WP_Error",{"type":47,"value":621}," on failure; the runner routes that through the stage's ",{"type":41,"tag":125,"props":623,"children":625},{"className":624},[],[626],{"type":47,"value":627},"error",{"type":47,"value":629}," destination.",{"type":41,"tag":75,"props":631,"children":632},{},[633,638,640,646,648,654,656,662,664,670,672,678,680,686,688,694,696,702,704,710,711,717,719,725],{"type":41,"tag":56,"props":634,"children":635},{},[636],{"type":47,"value":637},"Mutability contract",{"type":47,"value":639}," — read-only agents should declare ",{"type":41,"tag":125,"props":641,"children":643},{"className":642},[],[644],{"type":47,"value":645},"annotations.readonly => true",{"type":47,"value":647},". Mutating agents must write through ",{"type":41,"tag":125,"props":649,"children":651},{"className":650},[],[652],{"type":47,"value":653},"StageAgent",{"type":47,"value":655},": use ",{"type":41,"tag":125,"props":657,"children":659},{"className":658},[],[660],{"type":47,"value":661},"StageAgent::write_content()",{"type":47,"value":663}," to rewrite the body, or ",{"type":41,"tag":125,"props":665,"children":667},{"className":666},[],[668],{"type":47,"value":669},"StageAgent::write_block_notes()",{"type":47,"value":671}," to annotate blocks with native editorial notes (",{"type":41,"tag":125,"props":673,"children":675},{"className":674},[],[676],{"type":47,"value":677},"comment_type => 'note'",{"type":47,"value":679},", anchored via the block's ",{"type":41,"tag":125,"props":681,"children":683},{"className":682},[],[684],{"type":47,"value":685},"metadata.noteId",{"type":47,"value":687},"). Both sanitize content and attribute the change to the acting user. A note-writing agent is not read-only (",{"type":41,"tag":125,"props":689,"children":691},{"className":690},[],[692],{"type":47,"value":693},"annotations.readonly => false",{"type":47,"value":695},"). Native notes render in the editor's Comments panel for post types that declare ",{"type":41,"tag":125,"props":697,"children":699},{"className":698},[],[700],{"type":47,"value":701},"editor => notes",{"type":47,"value":703}," support (",{"type":41,"tag":125,"props":705,"children":707},{"className":706},[],[708],{"type":47,"value":709},"post",{"type":47,"value":605},{"type":41,"tag":125,"props":712,"children":714},{"className":713},[],[715],{"type":47,"value":716},"page",{"type":47,"value":718}," do by default; a custom type needs ",{"type":41,"tag":125,"props":720,"children":722},{"className":721},[],[723],{"type":47,"value":724},"add_post_type_support( $type, 'notes' )",{"type":47,"value":726},").",{"type":41,"tag":50,"props":728,"children":729},{},[730,735,737,743,745,750,752,757,759,764,766,772],{"type":41,"tag":56,"props":731,"children":732},{},[733],{"type":47,"value":734},"Routing",{"type":47,"value":736}," (authored on the stage, not the agent): ",{"type":41,"tag":125,"props":738,"children":740},{"className":739},[],[741],{"type":47,"value":742},"agent.routing = { pass, fail, error }",{"type":47,"value":744},", where each value is a status key that must be one of that stage's configured transitions. Every key is optional, ",{"type":41,"tag":125,"props":746,"children":748},{"className":747},[],[749],{"type":47,"value":627},{"type":47,"value":751}," included: when ",{"type":41,"tag":125,"props":753,"children":755},{"className":754},[],[756],{"type":47,"value":627},{"type":47,"value":758}," is routed, the runner sends a ",{"type":41,"tag":125,"props":760,"children":762},{"className":761},[],[763],{"type":47,"value":619},{"type":47,"value":765},", an invalid contract result, or any unrouted outcome there; without it, an errored run fails in place and the editor offers a \"go back to the previous stage\" action. The engine (",{"type":41,"tag":125,"props":767,"children":769},{"className":768},[],[770],{"type":47,"value":771},"StageAgentRunner",{"type":47,"value":773},") runs the agent asynchronously on stage entry, gates human transitions while it runs (and while it sits failed with a go-back available), and performs the exit transition as the agent — humans can only ever take the routed destinations.",{"type":41,"tag":50,"props":775,"children":776},{},[777,779,784,786,791,793,798],{"type":47,"value":778},"In the Sequence editor these are authored on the canvas, not in a form: choosing an agent in the stage inspector is what makes the stage AI-owned, and the node then carries three colored source handles — green ",{"type":41,"tag":125,"props":780,"children":782},{"className":781},[],[783],{"type":47,"value":573},{"type":47,"value":785},", red ",{"type":41,"tag":125,"props":787,"children":789},{"className":788},[],[790],{"type":47,"value":581},{"type":47,"value":792},", amber ",{"type":41,"tag":125,"props":794,"children":796},{"className":795},[],[797],{"type":47,"value":627},{"type":47,"value":799},". Dragging one onto another stage sets that outcome's destination and creates the transition it travels on. The inspector reads the routes back but does not edit them.",{"type":41,"tag":50,"props":801,"children":802},{},[803,808,810,816],{"type":41,"tag":56,"props":804,"children":805},{},[806],{"type":47,"value":807},"An AI stage's other transitions are disabled.",{"type":47,"value":809}," The agent owns the way out, so any transition no outcome routes along is inert: ",{"type":41,"tag":125,"props":811,"children":813},{"className":812},[],[814],{"type":47,"value":815},"StatusManager::get_available_transitions()",{"type":47,"value":817}," withholds it (the block editor offers no buttons while the agent works), and the canvas draws it dashed and grey. Nothing is deleted — the transition keeps its roles, tools, and notifications, and goes live again the moment an outcome is routed along it or the agent is taken off the stage. The withholding is scoped to a run actually being in flight: a failed run, or a stage that gained its agent while posts were already sitting in it, hands the transitions back rather than stranding the post.",{"type":41,"tag":819,"props":820,"children":821},"blockquote",{},[822],{"type":41,"tag":50,"props":823,"children":824},{},[825],{"type":47,"value":826},"Audit logging and revision attribution for agent stages are tracked separately.",{"type":41,"tag":819,"props":828,"children":829},{},[830],{"type":41,"tag":50,"props":831,"children":832},{},[833,838,840,846,848,853,854,859,861,867],{"type":41,"tag":56,"props":834,"children":835},{},[836],{"type":47,"value":837},"Agent stages are not reproducible.",{"type":47,"value":839}," ",{"type":41,"tag":125,"props":841,"children":843},{"className":842},[],[844],{"type":47,"value":845},"StageAgent::generate()",{"type":47,"value":847}," requests no sampling temperature and offers no way to ask for one, so identical inputs may produce different output — including a different ",{"type":41,"tag":125,"props":849,"children":851},{"className":850},[],[852],{"type":47,"value":573},{"type":47,"value":605},{"type":41,"tag":125,"props":855,"children":857},{"className":856},[],[858],{"type":47,"value":581},{"type":47,"value":860}," verdict on the same post. Mechanical stages (reformatting, tag sanity) briefly pinned temperature to 0 and did promise stable output; that promise is withdrawn. Newer Claude models refuse any request carrying the option, answering with HTTP 400 rather than ignoring it, and the AI Client's model metadata cannot be used to send it selectively — the Anthropic provider applies one hardcoded option list to every model it enumerates, advertising ",{"type":41,"tag":125,"props":862,"children":864},{"className":863},[],[865],{"type":47,"value":866},"temperature",{"type":47,"value":868}," as supported even where the API rejects it. Sending it only to models believed to accept it would be a guess, so it is not sent at all. Do not write an agent whose correctness depends on run-to-run stability.",{"type":41,"tag":134,"props":870,"children":872},{"id":871},"requirements",[873],{"type":47,"value":874},"Requirements",{"type":41,"tag":50,"props":876,"children":877},{},[878],{"type":47,"value":879},"Before starting, gather from the user:",{"type":41,"tag":430,"props":881,"children":882},{},[883,893,917,940,972,982,1015,1049,1090],{"type":41,"tag":75,"props":884,"children":885},{},[886,891],{"type":41,"tag":56,"props":887,"children":888},{},[889],{"type":47,"value":890},"Shape",{"type":47,"value":892}," — research, discovery, stage, or a combination?",{"type":41,"tag":75,"props":894,"children":895},{},[896,901,903,908,910,915],{"type":41,"tag":56,"props":897,"children":898},{},[899],{"type":47,"value":900},"For discovery",{"type":47,"value":902}," — does it support ",{"type":41,"tag":125,"props":904,"children":906},{"className":905},[],[907],{"type":47,"value":271},{"type":47,"value":909},", ",{"type":41,"tag":125,"props":911,"children":913},{"className":912},[],[914],{"type":47,"value":279},{"type":47,"value":916},", or both?",{"type":41,"tag":75,"props":918,"children":919},{},[920,925,927,932,933,938],{"type":41,"tag":56,"props":921,"children":922},{},[923],{"type":47,"value":924},"For stage",{"type":47,"value":926}," — read-only or mutating? A binary ",{"type":41,"tag":125,"props":928,"children":930},{"className":929},[],[931],{"type":47,"value":573},{"type":47,"value":605},{"type":41,"tag":125,"props":934,"children":936},{"className":935},[],[937],{"type":47,"value":581},{"type":47,"value":939}," judgment, and what data should appear in the result payload?",{"type":41,"tag":75,"props":941,"children":942},{},[943,947,949,954,956,962,964,970],{"type":41,"tag":56,"props":944,"children":945},{},[946],{"type":47,"value":924},{"type":47,"value":948}," — what post inputs and settings does it need? Stage agents should always require ",{"type":41,"tag":125,"props":950,"children":952},{"className":951},[],[953],{"type":47,"value":448},{"type":47,"value":955},"; optional settings belong in the agent's ",{"type":41,"tag":125,"props":957,"children":959},{"className":958},[],[960],{"type":47,"value":961},"settings_schema",{"type":47,"value":963}," or in the stage's ",{"type":41,"tag":125,"props":965,"children":967},{"className":966},[],[968],{"type":47,"value":969},"agent.settings",{"type":47,"value":971},".",{"type":41,"tag":75,"props":973,"children":974},{},[975,980],{"type":41,"tag":56,"props":976,"children":977},{},[978],{"type":47,"value":979},"Data source",{"type":47,"value":981}," — what API or service? (e.g., Reddit, PubMed, Foresight News, a wire service, an internal CMS, or an AI prompt over the current post)",{"type":41,"tag":75,"props":983,"children":984},{},[985,990,992,998,999,1005,1007,1013],{"type":41,"tag":56,"props":986,"children":987},{},[988],{"type":47,"value":989},"Plugin slug",{"type":47,"value":991}," — e.g., ",{"type":41,"tag":125,"props":993,"children":995},{"className":994},[],[996],{"type":47,"value":997},"workflow-agent-reddit",{"type":47,"value":909},{"type":41,"tag":125,"props":1000,"children":1002},{"className":1001},[],[1003],{"type":47,"value":1004},"workflow-agent-copy-edit",{"type":47,"value":1006},", or ",{"type":41,"tag":125,"props":1008,"children":1010},{"className":1009},[],[1011],{"type":47,"value":1012},"workflow-qwoted",{"type":47,"value":1014}," for combined",{"type":41,"tag":75,"props":1016,"children":1017},{},[1018,1023,1025,1031,1033,1039,1041,1047],{"type":41,"tag":56,"props":1019,"children":1020},{},[1021],{"type":47,"value":1022},"Namespaced IDs",{"type":47,"value":1024}," — ability ID like ",{"type":41,"tag":125,"props":1026,"children":1028},{"className":1027},[],[1029],{"type":47,"value":1030},"workflow-agent-reddit\u002Freddit",{"type":47,"value":1032}," (research), ",{"type":41,"tag":125,"props":1034,"children":1036},{"className":1035},[],[1037],{"type":47,"value":1038},"workflow-agent-copy-edit\u002Fcopy-edit",{"type":47,"value":1040}," (stage), or provider slug like ",{"type":41,"tag":125,"props":1042,"children":1044},{"className":1043},[],[1045],{"type":47,"value":1046},"my-news-source",{"type":47,"value":1048}," (discovery)",{"type":41,"tag":75,"props":1050,"children":1051},{},[1052,1057,1059,1065,1066,1072,1074,1080,1082,1088],{"type":41,"tag":56,"props":1053,"children":1054},{},[1055],{"type":47,"value":1056},"Icon",{"type":47,"value":1058}," — an icon slug (e.g. ",{"type":41,"tag":125,"props":1060,"children":1062},{"className":1061},[],[1063],{"type":47,"value":1064},"'search'",{"type":47,"value":909},{"type":41,"tag":125,"props":1067,"children":1069},{"className":1068},[],[1070],{"type":47,"value":1071},"'calendar'",{"type":47,"value":1073},"), from the set in\n",{"type":41,"tag":125,"props":1075,"children":1077},{"className":1076},[],[1078],{"type":47,"value":1079},"src\u002Fadmin\u002Fcomponents\u002Fideation\u002Fassistant-icon.js",{"type":47,"value":1081},". Not an emoji: the admin\nrenders these through ",{"type":41,"tag":125,"props":1083,"children":1085},{"className":1084},[],[1086],{"type":47,"value":1087},"@wordpress\u002Ficons",{"type":47,"value":1089},", and an unknown slug renders nothing.",{"type":41,"tag":75,"props":1091,"children":1092},{},[1093,1098,1100,1105,1107,1113,1114,1120,1122,1128,1130,1136,1138,1144,1146,1152,1153,1159,1161],{"type":41,"tag":56,"props":1094,"children":1095},{},[1096],{"type":47,"value":1097},"Credentials?",{"type":47,"value":1099}," — does it need an API key? Determines ",{"type":41,"tag":125,"props":1101,"children":1103},{"className":1102},[],[1104],{"type":47,"value":961},{"type":47,"value":1106}," and ",{"type":41,"tag":125,"props":1108,"children":1110},{"className":1109},[],[1111],{"type":47,"value":1112},"availability_callback",{"type":47,"value":273},{"type":41,"tag":125,"props":1115,"children":1117},{"className":1116},[],[1118],{"type":47,"value":1119},"is_configured",{"type":47,"value":1121},". Where does the key come from — the agent's own card fields (",{"type":41,"tag":125,"props":1123,"children":1125},{"className":1124},[],[1126],{"type":47,"value":1127},"RequirementFactory::in_card()",{"type":47,"value":1129},"), a service the plugin reads through ",{"type":41,"tag":125,"props":1131,"children":1133},{"className":1132},[],[1134],{"type":47,"value":1135},"VIPWorkflows\\AI\\Credentials",{"type":47,"value":1137}," (",{"type":41,"tag":125,"props":1139,"children":1141},{"className":1140},[],[1142],{"type":47,"value":1143},"RequirementFactory::missing_credential()",{"type":47,"value":1145},"), or nowhere the user can act on (",{"type":41,"tag":125,"props":1147,"children":1149},{"className":1148},[],[1150],{"type":47,"value":1151},"unsupported_environment()",{"type":47,"value":273},{"type":41,"tag":125,"props":1154,"children":1156},{"className":1155},[],[1157],{"type":47,"value":1158},"dependency()",{"type":47,"value":1160},")? See ",{"type":41,"tag":1162,"props":1163,"children":1165},"a",{"href":1164},"#availability",[1166],{"type":47,"value":1167},"Availability",{"type":41,"tag":134,"props":1169,"children":1171},{"id":1170},"plugin-structure",[1172],{"type":47,"value":1173},"Plugin Structure",{"type":41,"tag":1175,"props":1176,"children":1180},"pre",{"className":1177,"code":1179,"language":47},[1178],"language-text","workflow-{name}\u002F\n  workflow-{name}.php   # Main plugin file (single file is fine for most agents)\n",[1181],{"type":41,"tag":125,"props":1182,"children":1184},{"__ignoreMap":1183},"",[1185],{"type":47,"value":1179},{"type":41,"tag":50,"props":1187,"children":1188},{},[1189,1191,1197],{"type":47,"value":1190},"The plugin directory lives alongside ",{"type":41,"tag":125,"props":1192,"children":1194},{"className":1193},[],[1195],{"type":47,"value":1196},"vip-workflows\u002F",{"type":47,"value":1198}," in the same parent directory (not inside it).",{"type":41,"tag":50,"props":1200,"children":1201},{},[1202],{"type":47,"value":1203},"Naming conventions (not enforced, but keep things scannable):",{"type":41,"tag":71,"props":1205,"children":1206},{},[1207,1227,1244,1263],{"type":41,"tag":75,"props":1208,"children":1209},{},[1210,1212,1218,1220,1226],{"type":47,"value":1211},"Research-only: ",{"type":41,"tag":125,"props":1213,"children":1215},{"className":1214},[],[1216],{"type":47,"value":1217},"workflow-agent-{name}",{"type":47,"value":1219}," (e.g., ",{"type":41,"tag":125,"props":1221,"children":1223},{"className":1222},[],[1224],{"type":47,"value":1225},"workflow-agent-wikipedia",{"type":47,"value":296},{"type":41,"tag":75,"props":1228,"children":1229},{},[1230,1232,1237,1238,1243],{"type":47,"value":1231},"Stage-only: ",{"type":41,"tag":125,"props":1233,"children":1235},{"className":1234},[],[1236],{"type":47,"value":1217},{"type":47,"value":1219},{"type":41,"tag":125,"props":1239,"children":1241},{"className":1240},[],[1242],{"type":47,"value":1004},{"type":47,"value":296},{"type":41,"tag":75,"props":1245,"children":1246},{},[1247,1249,1255,1256,1262],{"type":47,"value":1248},"Discovery-only: ",{"type":41,"tag":125,"props":1250,"children":1252},{"className":1251},[],[1253],{"type":47,"value":1254},"workflow-discovery-{name}",{"type":47,"value":1219},{"type":41,"tag":125,"props":1257,"children":1259},{"className":1258},[],[1260],{"type":47,"value":1261},"workflow-discovery-newswire",{"type":47,"value":296},{"type":41,"tag":75,"props":1264,"children":1265},{},[1266,1268,1274,1275,1280],{"type":47,"value":1267},"Both: ",{"type":41,"tag":125,"props":1269,"children":1271},{"className":1270},[],[1272],{"type":47,"value":1273},"workflow-{name}",{"type":47,"value":1219},{"type":41,"tag":125,"props":1276,"children":1278},{"className":1277},[],[1279],{"type":47,"value":1012},{"type":47,"value":296},{"type":41,"tag":134,"props":1282,"children":1284},{"id":1283},"boilerplate-research-only",[1285],{"type":47,"value":1286},"Boilerplate: Research-Only",{"type":41,"tag":50,"props":1288,"children":1289},{},[1290],{"type":47,"value":1291},"Use this when the agent only runs during ideation on the mood board.",{"type":41,"tag":1175,"props":1293,"children":1297},{"className":1294,"code":1295,"language":1296,"meta":1183,"style":1183},"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C?php\n\u002F**\n * Plugin Name: Workflow Agent: {Display Name}\n * Description: Research agent that searches {data source} during ideation.\n * Version: 1.0.0\n * Requires Plugins: vip-workflows\n * Text Domain: workflow-agent-{name}\n *\n * @package WorkflowAgent{PascalName}\n *\u002F\n\ndeclare( strict_types=1 );\n\nnamespace WorkflowAgent{PascalName};\n\nif ( ! defined( 'ABSPATH' ) ) {\n    exit;\n}\n\nadd_action( 'wp_abilities_api_init', __NAMESPACE__ . '\\register' );\n\nfunction register(): void {\n    if ( ! function_exists( 'vip_workflows_register_ability' ) ) {\n        return;\n    }\n\n    vip_workflows_register_ability(\n        'workflow-agent-{name}\u002F{slug}',\n        array(\n            'label'               => __( '{Display Name}', 'workflow-agent-{name}' ),\n            'description'         => __( '{One-line description of what this searches.}', 'workflow-agent-{name}' ),\n            'category'            => 'research',\n            'input_schema'        => array(\n                'type'       => 'object',\n                'properties' => array(\n                    'seed'          => array( 'type' => 'string' ),\n                    'seed_analysis' => array( 'type' => 'object' ),\n                    'project_id'    => array( 'type' => 'integer' ),\n                    'query'         => array( 'type' => 'string' ),\n                    'brand_context' => array( 'type' => 'array' ),\n                ),\n                'required'   => array( 'seed' ),\n            ),\n            'output_schema'       => array(\n                'type'       => 'object',\n                'properties' => array(\n                    'cards'   => array( 'type' => 'array' ),\n                    'summary' => array( 'type' => 'string' ),\n                ),\n            ),\n            'execute_callback'    => __NAMESPACE__ . '\\execute',\n            'permission_callback' => function () {\n                return current_user_can( 'edit_posts' );\n            },\n            'meta'                => array(\n                'type'             => 'research',\n                'display_order'    => 50,\n                'show_in_rest'     => true,\n                'icon'             => 'search',\n                'thinking_message' => __( 'Searching {source}...', 'workflow-agent-{name}' ),\n                'success_message'  => __( '{Source} search complete.', 'workflow-agent-{name}' ),\n                \u002F\u002F Uncomment if the agent needs configuration:\n                \u002F\u002F 'settings_schema'  => array(\n                \u002F\u002F     'api_key' => array(\n                \u002F\u002F         'type'     => 'string',\n                \u002F\u002F         'label'    => 'API Key',\n                \u002F\u002F         'required' => true,\n                \u002F\u002F         'secret'   => true,\n                \u002F\u002F     ),\n                \u002F\u002F     'max_results' => array(\n                \u002F\u002F         'type'    => 'integer',\n                \u002F\u002F         'label'   => 'Max Results',\n                \u002F\u002F         'default' => 10,\n                \u002F\u002F         'minimum' => 1,\n                \u002F\u002F         'maximum' => 50,\n                \u002F\u002F     ),\n                \u002F\u002F ),\n                \u002F\u002F See the Availability section below for the callback body.\n                \u002F\u002F 'availability_callback' => __NAMESPACE__ . '\\check_availability',\n            ),\n        )\n    );\n}\n\n\u002F**\n * Execute the research search.\n *\n * When `query` is present (manual follow-up), search that term directly.\n * Otherwise use targeted search_queries from seed analysis, falling back\n * to the raw seed only if analysis produced nothing.\n *\n * @param array $input { seed: string, seed_analysis: array, query?: string, brand_context?: array }\n * @return array { cards: array, summary: string }\n *\u002F\nfunction execute( array $input ): array {\n    $seed_analysis = $input['seed_analysis'] ?? array();\n\n    if ( ! empty( $input['query'] ) ) {\n        $queries = array( $input['query'] );\n    } else {\n        $queries = $seed_analysis['search_queries'] ?? array();\n        if ( empty( $queries ) ) {\n            $queries = array( $input['seed'] ?? '' );\n        }\n    }\n\n    $queries = array_filter( $queries );\n    if ( empty( $queries ) ) {\n        return array( 'cards' => array(), 'summary' => 'No search query provided.' );\n    }\n\n    $all_cards = array();\n    foreach ( array_slice( $queries, 0, 3 ) as $query ) {\n        $all_cards = array_merge( $all_cards, search_source( $query ) );\n    }\n\n    return array(\n        'cards'   => $all_cards,\n        'summary' => sprintf( 'Found %d results.', count( $all_cards ) ),\n    );\n}\n\nfunction search_source( string $query ): array {\n    $url      = add_query_arg( array( 'q' => $query ), 'https:\u002F\u002Fapi.example.com\u002Fsearch' );\n    $response = wp_remote_get( $url, array( 'timeout' => 10 ) );\n\n    if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {\n        return array();\n    }\n\n    $body    = json_decode( wp_remote_retrieve_body( $response ), true );\n    $results = $body['results'] ?? array();\n    $cards   = array();\n\n    foreach ( array_slice( $results, 0, 10 ) as $item ) {\n        $cards[] = array(\n            'type'        => 'article',\n            'source_type' => 'article',\n            'origin'      => '{name}',\n            'title'       => $item['title'] ?? '',\n            'url'         => $item['url'] ?? '',\n            'excerpt'     => $item['description'] ?? '',\n            'content'     => $item['body'] ?? '',\n            'domain'      => '{domain.com}',\n            'author'      => $item['author'] ?? null,\n            'date'        => $item['date'] ?? null,\n            'image'       => $item['image'] ?? null,\n            'source'      => '{name}',\n        );\n    }\n\n    return $cards;\n}\n","php",[1298],{"type":41,"tag":125,"props":1299,"children":1300},{"__ignoreMap":1183},[1301,1312,1321,1330,1339,1348,1357,1366,1375,1384,1393,1403,1412,1420,1429,1437,1446,1455,1464,1472,1481,1489,1498,1507,1516,1525,1533,1542,1551,1560,1569,1578,1587,1596,1605,1614,1623,1632,1640,1649,1658,1667,1676,1685,1694,1702,1710,1719,1728,1736,1744,1753,1762,1771,1780,1789,1798,1807,1816,1825,1834,1843,1852,1861,1870,1879,1888,1897,1906,1915,1924,1933,1942,1951,1960,1969,1977,1986,1995,2004,2012,2021,2030,2038,2046,2054,2063,2071,2080,2089,2098,2106,2115,2124,2132,2141,2150,2158,2167,2176,2185,2194,2203,2212,2221,2229,2237,2246,2255,2264,2272,2280,2289,2298,2307,2315,2323,2332,2341,2350,2358,2366,2374,2383,2392,2401,2409,2418,2427,2435,2443,2452,2461,2470,2478,2487,2496,2505,2514,2523,2532,2541,2550,2559,2568,2577,2586,2595,2604,2613,2620,2628,2637],{"type":41,"tag":1302,"props":1303,"children":1306},"span",{"class":1304,"line":1305},"line",1,[1307],{"type":41,"tag":1302,"props":1308,"children":1309},{},[1310],{"type":47,"value":1311},"\u003C?php\n",{"type":41,"tag":1302,"props":1313,"children":1315},{"class":1304,"line":1314},2,[1316],{"type":41,"tag":1302,"props":1317,"children":1318},{},[1319],{"type":47,"value":1320},"\u002F**\n",{"type":41,"tag":1302,"props":1322,"children":1324},{"class":1304,"line":1323},3,[1325],{"type":41,"tag":1302,"props":1326,"children":1327},{},[1328],{"type":47,"value":1329}," * Plugin Name: Workflow Agent: {Display Name}\n",{"type":41,"tag":1302,"props":1331,"children":1333},{"class":1304,"line":1332},4,[1334],{"type":41,"tag":1302,"props":1335,"children":1336},{},[1337],{"type":47,"value":1338}," * Description: Research agent that searches {data source} during ideation.\n",{"type":41,"tag":1302,"props":1340,"children":1342},{"class":1304,"line":1341},5,[1343],{"type":41,"tag":1302,"props":1344,"children":1345},{},[1346],{"type":47,"value":1347}," * Version: 1.0.0\n",{"type":41,"tag":1302,"props":1349,"children":1351},{"class":1304,"line":1350},6,[1352],{"type":41,"tag":1302,"props":1353,"children":1354},{},[1355],{"type":47,"value":1356}," * Requires Plugins: vip-workflows\n",{"type":41,"tag":1302,"props":1358,"children":1360},{"class":1304,"line":1359},7,[1361],{"type":41,"tag":1302,"props":1362,"children":1363},{},[1364],{"type":47,"value":1365}," * Text Domain: workflow-agent-{name}\n",{"type":41,"tag":1302,"props":1367,"children":1369},{"class":1304,"line":1368},8,[1370],{"type":41,"tag":1302,"props":1371,"children":1372},{},[1373],{"type":47,"value":1374}," *\n",{"type":41,"tag":1302,"props":1376,"children":1378},{"class":1304,"line":1377},9,[1379],{"type":41,"tag":1302,"props":1380,"children":1381},{},[1382],{"type":47,"value":1383}," * @package WorkflowAgent{PascalName}\n",{"type":41,"tag":1302,"props":1385,"children":1387},{"class":1304,"line":1386},10,[1388],{"type":41,"tag":1302,"props":1389,"children":1390},{},[1391],{"type":47,"value":1392}," *\u002F\n",{"type":41,"tag":1302,"props":1394,"children":1396},{"class":1304,"line":1395},11,[1397],{"type":41,"tag":1302,"props":1398,"children":1400},{"emptyLinePlaceholder":1399},true,[1401],{"type":47,"value":1402},"\n",{"type":41,"tag":1302,"props":1404,"children":1406},{"class":1304,"line":1405},12,[1407],{"type":41,"tag":1302,"props":1408,"children":1409},{},[1410],{"type":47,"value":1411},"declare( strict_types=1 );\n",{"type":41,"tag":1302,"props":1413,"children":1415},{"class":1304,"line":1414},13,[1416],{"type":41,"tag":1302,"props":1417,"children":1418},{"emptyLinePlaceholder":1399},[1419],{"type":47,"value":1402},{"type":41,"tag":1302,"props":1421,"children":1423},{"class":1304,"line":1422},14,[1424],{"type":41,"tag":1302,"props":1425,"children":1426},{},[1427],{"type":47,"value":1428},"namespace WorkflowAgent{PascalName};\n",{"type":41,"tag":1302,"props":1430,"children":1432},{"class":1304,"line":1431},15,[1433],{"type":41,"tag":1302,"props":1434,"children":1435},{"emptyLinePlaceholder":1399},[1436],{"type":47,"value":1402},{"type":41,"tag":1302,"props":1438,"children":1440},{"class":1304,"line":1439},16,[1441],{"type":41,"tag":1302,"props":1442,"children":1443},{},[1444],{"type":47,"value":1445},"if ( ! defined( 'ABSPATH' ) ) {\n",{"type":41,"tag":1302,"props":1447,"children":1449},{"class":1304,"line":1448},17,[1450],{"type":41,"tag":1302,"props":1451,"children":1452},{},[1453],{"type":47,"value":1454},"    exit;\n",{"type":41,"tag":1302,"props":1456,"children":1458},{"class":1304,"line":1457},18,[1459],{"type":41,"tag":1302,"props":1460,"children":1461},{},[1462],{"type":47,"value":1463},"}\n",{"type":41,"tag":1302,"props":1465,"children":1467},{"class":1304,"line":1466},19,[1468],{"type":41,"tag":1302,"props":1469,"children":1470},{"emptyLinePlaceholder":1399},[1471],{"type":47,"value":1402},{"type":41,"tag":1302,"props":1473,"children":1475},{"class":1304,"line":1474},20,[1476],{"type":41,"tag":1302,"props":1477,"children":1478},{},[1479],{"type":47,"value":1480},"add_action( 'wp_abilities_api_init', __NAMESPACE__ . '\\register' );\n",{"type":41,"tag":1302,"props":1482,"children":1484},{"class":1304,"line":1483},21,[1485],{"type":41,"tag":1302,"props":1486,"children":1487},{"emptyLinePlaceholder":1399},[1488],{"type":47,"value":1402},{"type":41,"tag":1302,"props":1490,"children":1492},{"class":1304,"line":1491},22,[1493],{"type":41,"tag":1302,"props":1494,"children":1495},{},[1496],{"type":47,"value":1497},"function register(): void {\n",{"type":41,"tag":1302,"props":1499,"children":1501},{"class":1304,"line":1500},23,[1502],{"type":41,"tag":1302,"props":1503,"children":1504},{},[1505],{"type":47,"value":1506},"    if ( ! function_exists( 'vip_workflows_register_ability' ) ) {\n",{"type":41,"tag":1302,"props":1508,"children":1510},{"class":1304,"line":1509},24,[1511],{"type":41,"tag":1302,"props":1512,"children":1513},{},[1514],{"type":47,"value":1515},"        return;\n",{"type":41,"tag":1302,"props":1517,"children":1519},{"class":1304,"line":1518},25,[1520],{"type":41,"tag":1302,"props":1521,"children":1522},{},[1523],{"type":47,"value":1524},"    }\n",{"type":41,"tag":1302,"props":1526,"children":1528},{"class":1304,"line":1527},26,[1529],{"type":41,"tag":1302,"props":1530,"children":1531},{"emptyLinePlaceholder":1399},[1532],{"type":47,"value":1402},{"type":41,"tag":1302,"props":1534,"children":1536},{"class":1304,"line":1535},27,[1537],{"type":41,"tag":1302,"props":1538,"children":1539},{},[1540],{"type":47,"value":1541},"    vip_workflows_register_ability(\n",{"type":41,"tag":1302,"props":1543,"children":1545},{"class":1304,"line":1544},28,[1546],{"type":41,"tag":1302,"props":1547,"children":1548},{},[1549],{"type":47,"value":1550},"        'workflow-agent-{name}\u002F{slug}',\n",{"type":41,"tag":1302,"props":1552,"children":1554},{"class":1304,"line":1553},29,[1555],{"type":41,"tag":1302,"props":1556,"children":1557},{},[1558],{"type":47,"value":1559},"        array(\n",{"type":41,"tag":1302,"props":1561,"children":1563},{"class":1304,"line":1562},30,[1564],{"type":41,"tag":1302,"props":1565,"children":1566},{},[1567],{"type":47,"value":1568},"            'label'               => __( '{Display Name}', 'workflow-agent-{name}' ),\n",{"type":41,"tag":1302,"props":1570,"children":1572},{"class":1304,"line":1571},31,[1573],{"type":41,"tag":1302,"props":1574,"children":1575},{},[1576],{"type":47,"value":1577},"            'description'         => __( '{One-line description of what this searches.}', 'workflow-agent-{name}' ),\n",{"type":41,"tag":1302,"props":1579,"children":1581},{"class":1304,"line":1580},32,[1582],{"type":41,"tag":1302,"props":1583,"children":1584},{},[1585],{"type":47,"value":1586},"            'category'            => 'research',\n",{"type":41,"tag":1302,"props":1588,"children":1590},{"class":1304,"line":1589},33,[1591],{"type":41,"tag":1302,"props":1592,"children":1593},{},[1594],{"type":47,"value":1595},"            'input_schema'        => array(\n",{"type":41,"tag":1302,"props":1597,"children":1599},{"class":1304,"line":1598},34,[1600],{"type":41,"tag":1302,"props":1601,"children":1602},{},[1603],{"type":47,"value":1604},"                'type'       => 'object',\n",{"type":41,"tag":1302,"props":1606,"children":1608},{"class":1304,"line":1607},35,[1609],{"type":41,"tag":1302,"props":1610,"children":1611},{},[1612],{"type":47,"value":1613},"                'properties' => array(\n",{"type":41,"tag":1302,"props":1615,"children":1617},{"class":1304,"line":1616},36,[1618],{"type":41,"tag":1302,"props":1619,"children":1620},{},[1621],{"type":47,"value":1622},"                    'seed'          => array( 'type' => 'string' ),\n",{"type":41,"tag":1302,"props":1624,"children":1626},{"class":1304,"line":1625},37,[1627],{"type":41,"tag":1302,"props":1628,"children":1629},{},[1630],{"type":47,"value":1631},"                    'seed_analysis' => array( 'type' => 'object' ),\n",{"type":41,"tag":1302,"props":1633,"children":1634},{"class":1304,"line":26},[1635],{"type":41,"tag":1302,"props":1636,"children":1637},{},[1638],{"type":47,"value":1639},"                    'project_id'    => array( 'type' => 'integer' ),\n",{"type":41,"tag":1302,"props":1641,"children":1643},{"class":1304,"line":1642},39,[1644],{"type":41,"tag":1302,"props":1645,"children":1646},{},[1647],{"type":47,"value":1648},"                    'query'         => array( 'type' => 'string' ),\n",{"type":41,"tag":1302,"props":1650,"children":1652},{"class":1304,"line":1651},40,[1653],{"type":41,"tag":1302,"props":1654,"children":1655},{},[1656],{"type":47,"value":1657},"                    'brand_context' => array( 'type' => 'array' ),\n",{"type":41,"tag":1302,"props":1659,"children":1661},{"class":1304,"line":1660},41,[1662],{"type":41,"tag":1302,"props":1663,"children":1664},{},[1665],{"type":47,"value":1666},"                ),\n",{"type":41,"tag":1302,"props":1668,"children":1670},{"class":1304,"line":1669},42,[1671],{"type":41,"tag":1302,"props":1672,"children":1673},{},[1674],{"type":47,"value":1675},"                'required'   => array( 'seed' ),\n",{"type":41,"tag":1302,"props":1677,"children":1679},{"class":1304,"line":1678},43,[1680],{"type":41,"tag":1302,"props":1681,"children":1682},{},[1683],{"type":47,"value":1684},"            ),\n",{"type":41,"tag":1302,"props":1686,"children":1688},{"class":1304,"line":1687},44,[1689],{"type":41,"tag":1302,"props":1690,"children":1691},{},[1692],{"type":47,"value":1693},"            'output_schema'       => array(\n",{"type":41,"tag":1302,"props":1695,"children":1697},{"class":1304,"line":1696},45,[1698],{"type":41,"tag":1302,"props":1699,"children":1700},{},[1701],{"type":47,"value":1604},{"type":41,"tag":1302,"props":1703,"children":1705},{"class":1304,"line":1704},46,[1706],{"type":41,"tag":1302,"props":1707,"children":1708},{},[1709],{"type":47,"value":1613},{"type":41,"tag":1302,"props":1711,"children":1713},{"class":1304,"line":1712},47,[1714],{"type":41,"tag":1302,"props":1715,"children":1716},{},[1717],{"type":47,"value":1718},"                    'cards'   => array( 'type' => 'array' ),\n",{"type":41,"tag":1302,"props":1720,"children":1722},{"class":1304,"line":1721},48,[1723],{"type":41,"tag":1302,"props":1724,"children":1725},{},[1726],{"type":47,"value":1727},"                    'summary' => array( 'type' => 'string' ),\n",{"type":41,"tag":1302,"props":1729,"children":1731},{"class":1304,"line":1730},49,[1732],{"type":41,"tag":1302,"props":1733,"children":1734},{},[1735],{"type":47,"value":1666},{"type":41,"tag":1302,"props":1737,"children":1739},{"class":1304,"line":1738},50,[1740],{"type":41,"tag":1302,"props":1741,"children":1742},{},[1743],{"type":47,"value":1684},{"type":41,"tag":1302,"props":1745,"children":1747},{"class":1304,"line":1746},51,[1748],{"type":41,"tag":1302,"props":1749,"children":1750},{},[1751],{"type":47,"value":1752},"            'execute_callback'    => __NAMESPACE__ . '\\execute',\n",{"type":41,"tag":1302,"props":1754,"children":1756},{"class":1304,"line":1755},52,[1757],{"type":41,"tag":1302,"props":1758,"children":1759},{},[1760],{"type":47,"value":1761},"            'permission_callback' => function () {\n",{"type":41,"tag":1302,"props":1763,"children":1765},{"class":1304,"line":1764},53,[1766],{"type":41,"tag":1302,"props":1767,"children":1768},{},[1769],{"type":47,"value":1770},"                return current_user_can( 'edit_posts' );\n",{"type":41,"tag":1302,"props":1772,"children":1774},{"class":1304,"line":1773},54,[1775],{"type":41,"tag":1302,"props":1776,"children":1777},{},[1778],{"type":47,"value":1779},"            },\n",{"type":41,"tag":1302,"props":1781,"children":1783},{"class":1304,"line":1782},55,[1784],{"type":41,"tag":1302,"props":1785,"children":1786},{},[1787],{"type":47,"value":1788},"            'meta'                => array(\n",{"type":41,"tag":1302,"props":1790,"children":1792},{"class":1304,"line":1791},56,[1793],{"type":41,"tag":1302,"props":1794,"children":1795},{},[1796],{"type":47,"value":1797},"                'type'             => 'research',\n",{"type":41,"tag":1302,"props":1799,"children":1801},{"class":1304,"line":1800},57,[1802],{"type":41,"tag":1302,"props":1803,"children":1804},{},[1805],{"type":47,"value":1806},"                'display_order'    => 50,\n",{"type":41,"tag":1302,"props":1808,"children":1810},{"class":1304,"line":1809},58,[1811],{"type":41,"tag":1302,"props":1812,"children":1813},{},[1814],{"type":47,"value":1815},"                'show_in_rest'     => true,\n",{"type":41,"tag":1302,"props":1817,"children":1819},{"class":1304,"line":1818},59,[1820],{"type":41,"tag":1302,"props":1821,"children":1822},{},[1823],{"type":47,"value":1824},"                'icon'             => 'search',\n",{"type":41,"tag":1302,"props":1826,"children":1828},{"class":1304,"line":1827},60,[1829],{"type":41,"tag":1302,"props":1830,"children":1831},{},[1832],{"type":47,"value":1833},"                'thinking_message' => __( 'Searching {source}...', 'workflow-agent-{name}' ),\n",{"type":41,"tag":1302,"props":1835,"children":1837},{"class":1304,"line":1836},61,[1838],{"type":41,"tag":1302,"props":1839,"children":1840},{},[1841],{"type":47,"value":1842},"                'success_message'  => __( '{Source} search complete.', 'workflow-agent-{name}' ),\n",{"type":41,"tag":1302,"props":1844,"children":1846},{"class":1304,"line":1845},62,[1847],{"type":41,"tag":1302,"props":1848,"children":1849},{},[1850],{"type":47,"value":1851},"                \u002F\u002F Uncomment if the agent needs configuration:\n",{"type":41,"tag":1302,"props":1853,"children":1855},{"class":1304,"line":1854},63,[1856],{"type":41,"tag":1302,"props":1857,"children":1858},{},[1859],{"type":47,"value":1860},"                \u002F\u002F 'settings_schema'  => array(\n",{"type":41,"tag":1302,"props":1862,"children":1864},{"class":1304,"line":1863},64,[1865],{"type":41,"tag":1302,"props":1866,"children":1867},{},[1868],{"type":47,"value":1869},"                \u002F\u002F     'api_key' => array(\n",{"type":41,"tag":1302,"props":1871,"children":1873},{"class":1304,"line":1872},65,[1874],{"type":41,"tag":1302,"props":1875,"children":1876},{},[1877],{"type":47,"value":1878},"                \u002F\u002F         'type'     => 'string',\n",{"type":41,"tag":1302,"props":1880,"children":1882},{"class":1304,"line":1881},66,[1883],{"type":41,"tag":1302,"props":1884,"children":1885},{},[1886],{"type":47,"value":1887},"                \u002F\u002F         'label'    => 'API Key',\n",{"type":41,"tag":1302,"props":1889,"children":1891},{"class":1304,"line":1890},67,[1892],{"type":41,"tag":1302,"props":1893,"children":1894},{},[1895],{"type":47,"value":1896},"                \u002F\u002F         'required' => true,\n",{"type":41,"tag":1302,"props":1898,"children":1900},{"class":1304,"line":1899},68,[1901],{"type":41,"tag":1302,"props":1902,"children":1903},{},[1904],{"type":47,"value":1905},"                \u002F\u002F         'secret'   => true,\n",{"type":41,"tag":1302,"props":1907,"children":1909},{"class":1304,"line":1908},69,[1910],{"type":41,"tag":1302,"props":1911,"children":1912},{},[1913],{"type":47,"value":1914},"                \u002F\u002F     ),\n",{"type":41,"tag":1302,"props":1916,"children":1918},{"class":1304,"line":1917},70,[1919],{"type":41,"tag":1302,"props":1920,"children":1921},{},[1922],{"type":47,"value":1923},"                \u002F\u002F     'max_results' => array(\n",{"type":41,"tag":1302,"props":1925,"children":1927},{"class":1304,"line":1926},71,[1928],{"type":41,"tag":1302,"props":1929,"children":1930},{},[1931],{"type":47,"value":1932},"                \u002F\u002F         'type'    => 'integer',\n",{"type":41,"tag":1302,"props":1934,"children":1936},{"class":1304,"line":1935},72,[1937],{"type":41,"tag":1302,"props":1938,"children":1939},{},[1940],{"type":47,"value":1941},"                \u002F\u002F         'label'   => 'Max Results',\n",{"type":41,"tag":1302,"props":1943,"children":1945},{"class":1304,"line":1944},73,[1946],{"type":41,"tag":1302,"props":1947,"children":1948},{},[1949],{"type":47,"value":1950},"                \u002F\u002F         'default' => 10,\n",{"type":41,"tag":1302,"props":1952,"children":1954},{"class":1304,"line":1953},74,[1955],{"type":41,"tag":1302,"props":1956,"children":1957},{},[1958],{"type":47,"value":1959},"                \u002F\u002F         'minimum' => 1,\n",{"type":41,"tag":1302,"props":1961,"children":1963},{"class":1304,"line":1962},75,[1964],{"type":41,"tag":1302,"props":1965,"children":1966},{},[1967],{"type":47,"value":1968},"                \u002F\u002F         'maximum' => 50,\n",{"type":41,"tag":1302,"props":1970,"children":1972},{"class":1304,"line":1971},76,[1973],{"type":41,"tag":1302,"props":1974,"children":1975},{},[1976],{"type":47,"value":1914},{"type":41,"tag":1302,"props":1978,"children":1980},{"class":1304,"line":1979},77,[1981],{"type":41,"tag":1302,"props":1982,"children":1983},{},[1984],{"type":47,"value":1985},"                \u002F\u002F ),\n",{"type":41,"tag":1302,"props":1987,"children":1989},{"class":1304,"line":1988},78,[1990],{"type":41,"tag":1302,"props":1991,"children":1992},{},[1993],{"type":47,"value":1994},"                \u002F\u002F See the Availability section below for the callback body.\n",{"type":41,"tag":1302,"props":1996,"children":1998},{"class":1304,"line":1997},79,[1999],{"type":41,"tag":1302,"props":2000,"children":2001},{},[2002],{"type":47,"value":2003},"                \u002F\u002F 'availability_callback' => __NAMESPACE__ . '\\check_availability',\n",{"type":41,"tag":1302,"props":2005,"children":2007},{"class":1304,"line":2006},80,[2008],{"type":41,"tag":1302,"props":2009,"children":2010},{},[2011],{"type":47,"value":1684},{"type":41,"tag":1302,"props":2013,"children":2015},{"class":1304,"line":2014},81,[2016],{"type":41,"tag":1302,"props":2017,"children":2018},{},[2019],{"type":47,"value":2020},"        )\n",{"type":41,"tag":1302,"props":2022,"children":2024},{"class":1304,"line":2023},82,[2025],{"type":41,"tag":1302,"props":2026,"children":2027},{},[2028],{"type":47,"value":2029},"    );\n",{"type":41,"tag":1302,"props":2031,"children":2033},{"class":1304,"line":2032},83,[2034],{"type":41,"tag":1302,"props":2035,"children":2036},{},[2037],{"type":47,"value":1463},{"type":41,"tag":1302,"props":2039,"children":2041},{"class":1304,"line":2040},84,[2042],{"type":41,"tag":1302,"props":2043,"children":2044},{"emptyLinePlaceholder":1399},[2045],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2047,"children":2049},{"class":1304,"line":2048},85,[2050],{"type":41,"tag":1302,"props":2051,"children":2052},{},[2053],{"type":47,"value":1320},{"type":41,"tag":1302,"props":2055,"children":2057},{"class":1304,"line":2056},86,[2058],{"type":41,"tag":1302,"props":2059,"children":2060},{},[2061],{"type":47,"value":2062}," * Execute the research search.\n",{"type":41,"tag":1302,"props":2064,"children":2066},{"class":1304,"line":2065},87,[2067],{"type":41,"tag":1302,"props":2068,"children":2069},{},[2070],{"type":47,"value":1374},{"type":41,"tag":1302,"props":2072,"children":2074},{"class":1304,"line":2073},88,[2075],{"type":41,"tag":1302,"props":2076,"children":2077},{},[2078],{"type":47,"value":2079}," * When `query` is present (manual follow-up), search that term directly.\n",{"type":41,"tag":1302,"props":2081,"children":2083},{"class":1304,"line":2082},89,[2084],{"type":41,"tag":1302,"props":2085,"children":2086},{},[2087],{"type":47,"value":2088}," * Otherwise use targeted search_queries from seed analysis, falling back\n",{"type":41,"tag":1302,"props":2090,"children":2092},{"class":1304,"line":2091},90,[2093],{"type":41,"tag":1302,"props":2094,"children":2095},{},[2096],{"type":47,"value":2097}," * to the raw seed only if analysis produced nothing.\n",{"type":41,"tag":1302,"props":2099,"children":2101},{"class":1304,"line":2100},91,[2102],{"type":41,"tag":1302,"props":2103,"children":2104},{},[2105],{"type":47,"value":1374},{"type":41,"tag":1302,"props":2107,"children":2109},{"class":1304,"line":2108},92,[2110],{"type":41,"tag":1302,"props":2111,"children":2112},{},[2113],{"type":47,"value":2114}," * @param array $input { seed: string, seed_analysis: array, query?: string, brand_context?: array }\n",{"type":41,"tag":1302,"props":2116,"children":2118},{"class":1304,"line":2117},93,[2119],{"type":41,"tag":1302,"props":2120,"children":2121},{},[2122],{"type":47,"value":2123}," * @return array { cards: array, summary: string }\n",{"type":41,"tag":1302,"props":2125,"children":2127},{"class":1304,"line":2126},94,[2128],{"type":41,"tag":1302,"props":2129,"children":2130},{},[2131],{"type":47,"value":1392},{"type":41,"tag":1302,"props":2133,"children":2135},{"class":1304,"line":2134},95,[2136],{"type":41,"tag":1302,"props":2137,"children":2138},{},[2139],{"type":47,"value":2140},"function execute( array $input ): array {\n",{"type":41,"tag":1302,"props":2142,"children":2144},{"class":1304,"line":2143},96,[2145],{"type":41,"tag":1302,"props":2146,"children":2147},{},[2148],{"type":47,"value":2149},"    $seed_analysis = $input['seed_analysis'] ?? array();\n",{"type":41,"tag":1302,"props":2151,"children":2153},{"class":1304,"line":2152},97,[2154],{"type":41,"tag":1302,"props":2155,"children":2156},{"emptyLinePlaceholder":1399},[2157],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2159,"children":2161},{"class":1304,"line":2160},98,[2162],{"type":41,"tag":1302,"props":2163,"children":2164},{},[2165],{"type":47,"value":2166},"    if ( ! empty( $input['query'] ) ) {\n",{"type":41,"tag":1302,"props":2168,"children":2170},{"class":1304,"line":2169},99,[2171],{"type":41,"tag":1302,"props":2172,"children":2173},{},[2174],{"type":47,"value":2175},"        $queries = array( $input['query'] );\n",{"type":41,"tag":1302,"props":2177,"children":2179},{"class":1304,"line":2178},100,[2180],{"type":41,"tag":1302,"props":2181,"children":2182},{},[2183],{"type":47,"value":2184},"    } else {\n",{"type":41,"tag":1302,"props":2186,"children":2188},{"class":1304,"line":2187},101,[2189],{"type":41,"tag":1302,"props":2190,"children":2191},{},[2192],{"type":47,"value":2193},"        $queries = $seed_analysis['search_queries'] ?? array();\n",{"type":41,"tag":1302,"props":2195,"children":2197},{"class":1304,"line":2196},102,[2198],{"type":41,"tag":1302,"props":2199,"children":2200},{},[2201],{"type":47,"value":2202},"        if ( empty( $queries ) ) {\n",{"type":41,"tag":1302,"props":2204,"children":2206},{"class":1304,"line":2205},103,[2207],{"type":41,"tag":1302,"props":2208,"children":2209},{},[2210],{"type":47,"value":2211},"            $queries = array( $input['seed'] ?? '' );\n",{"type":41,"tag":1302,"props":2213,"children":2215},{"class":1304,"line":2214},104,[2216],{"type":41,"tag":1302,"props":2217,"children":2218},{},[2219],{"type":47,"value":2220},"        }\n",{"type":41,"tag":1302,"props":2222,"children":2224},{"class":1304,"line":2223},105,[2225],{"type":41,"tag":1302,"props":2226,"children":2227},{},[2228],{"type":47,"value":1524},{"type":41,"tag":1302,"props":2230,"children":2232},{"class":1304,"line":2231},106,[2233],{"type":41,"tag":1302,"props":2234,"children":2235},{"emptyLinePlaceholder":1399},[2236],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2238,"children":2240},{"class":1304,"line":2239},107,[2241],{"type":41,"tag":1302,"props":2242,"children":2243},{},[2244],{"type":47,"value":2245},"    $queries = array_filter( $queries );\n",{"type":41,"tag":1302,"props":2247,"children":2249},{"class":1304,"line":2248},108,[2250],{"type":41,"tag":1302,"props":2251,"children":2252},{},[2253],{"type":47,"value":2254},"    if ( empty( $queries ) ) {\n",{"type":41,"tag":1302,"props":2256,"children":2258},{"class":1304,"line":2257},109,[2259],{"type":41,"tag":1302,"props":2260,"children":2261},{},[2262],{"type":47,"value":2263},"        return array( 'cards' => array(), 'summary' => 'No search query provided.' );\n",{"type":41,"tag":1302,"props":2265,"children":2267},{"class":1304,"line":2266},110,[2268],{"type":41,"tag":1302,"props":2269,"children":2270},{},[2271],{"type":47,"value":1524},{"type":41,"tag":1302,"props":2273,"children":2275},{"class":1304,"line":2274},111,[2276],{"type":41,"tag":1302,"props":2277,"children":2278},{"emptyLinePlaceholder":1399},[2279],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2281,"children":2283},{"class":1304,"line":2282},112,[2284],{"type":41,"tag":1302,"props":2285,"children":2286},{},[2287],{"type":47,"value":2288},"    $all_cards = array();\n",{"type":41,"tag":1302,"props":2290,"children":2292},{"class":1304,"line":2291},113,[2293],{"type":41,"tag":1302,"props":2294,"children":2295},{},[2296],{"type":47,"value":2297},"    foreach ( array_slice( $queries, 0, 3 ) as $query ) {\n",{"type":41,"tag":1302,"props":2299,"children":2301},{"class":1304,"line":2300},114,[2302],{"type":41,"tag":1302,"props":2303,"children":2304},{},[2305],{"type":47,"value":2306},"        $all_cards = array_merge( $all_cards, search_source( $query ) );\n",{"type":41,"tag":1302,"props":2308,"children":2310},{"class":1304,"line":2309},115,[2311],{"type":41,"tag":1302,"props":2312,"children":2313},{},[2314],{"type":47,"value":1524},{"type":41,"tag":1302,"props":2316,"children":2318},{"class":1304,"line":2317},116,[2319],{"type":41,"tag":1302,"props":2320,"children":2321},{"emptyLinePlaceholder":1399},[2322],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2324,"children":2326},{"class":1304,"line":2325},117,[2327],{"type":41,"tag":1302,"props":2328,"children":2329},{},[2330],{"type":47,"value":2331},"    return array(\n",{"type":41,"tag":1302,"props":2333,"children":2335},{"class":1304,"line":2334},118,[2336],{"type":41,"tag":1302,"props":2337,"children":2338},{},[2339],{"type":47,"value":2340},"        'cards'   => $all_cards,\n",{"type":41,"tag":1302,"props":2342,"children":2344},{"class":1304,"line":2343},119,[2345],{"type":41,"tag":1302,"props":2346,"children":2347},{},[2348],{"type":47,"value":2349},"        'summary' => sprintf( 'Found %d results.', count( $all_cards ) ),\n",{"type":41,"tag":1302,"props":2351,"children":2353},{"class":1304,"line":2352},120,[2354],{"type":41,"tag":1302,"props":2355,"children":2356},{},[2357],{"type":47,"value":2029},{"type":41,"tag":1302,"props":2359,"children":2361},{"class":1304,"line":2360},121,[2362],{"type":41,"tag":1302,"props":2363,"children":2364},{},[2365],{"type":47,"value":1463},{"type":41,"tag":1302,"props":2367,"children":2369},{"class":1304,"line":2368},122,[2370],{"type":41,"tag":1302,"props":2371,"children":2372},{"emptyLinePlaceholder":1399},[2373],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2375,"children":2377},{"class":1304,"line":2376},123,[2378],{"type":41,"tag":1302,"props":2379,"children":2380},{},[2381],{"type":47,"value":2382},"function search_source( string $query ): array {\n",{"type":41,"tag":1302,"props":2384,"children":2386},{"class":1304,"line":2385},124,[2387],{"type":41,"tag":1302,"props":2388,"children":2389},{},[2390],{"type":47,"value":2391},"    $url      = add_query_arg( array( 'q' => $query ), 'https:\u002F\u002Fapi.example.com\u002Fsearch' );\n",{"type":41,"tag":1302,"props":2393,"children":2395},{"class":1304,"line":2394},125,[2396],{"type":41,"tag":1302,"props":2397,"children":2398},{},[2399],{"type":47,"value":2400},"    $response = wp_remote_get( $url, array( 'timeout' => 10 ) );\n",{"type":41,"tag":1302,"props":2402,"children":2404},{"class":1304,"line":2403},126,[2405],{"type":41,"tag":1302,"props":2406,"children":2407},{"emptyLinePlaceholder":1399},[2408],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2410,"children":2412},{"class":1304,"line":2411},127,[2413],{"type":41,"tag":1302,"props":2414,"children":2415},{},[2416],{"type":47,"value":2417},"    if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {\n",{"type":41,"tag":1302,"props":2419,"children":2421},{"class":1304,"line":2420},128,[2422],{"type":41,"tag":1302,"props":2423,"children":2424},{},[2425],{"type":47,"value":2426},"        return array();\n",{"type":41,"tag":1302,"props":2428,"children":2430},{"class":1304,"line":2429},129,[2431],{"type":41,"tag":1302,"props":2432,"children":2433},{},[2434],{"type":47,"value":1524},{"type":41,"tag":1302,"props":2436,"children":2438},{"class":1304,"line":2437},130,[2439],{"type":41,"tag":1302,"props":2440,"children":2441},{"emptyLinePlaceholder":1399},[2442],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2444,"children":2446},{"class":1304,"line":2445},131,[2447],{"type":41,"tag":1302,"props":2448,"children":2449},{},[2450],{"type":47,"value":2451},"    $body    = json_decode( wp_remote_retrieve_body( $response ), true );\n",{"type":41,"tag":1302,"props":2453,"children":2455},{"class":1304,"line":2454},132,[2456],{"type":41,"tag":1302,"props":2457,"children":2458},{},[2459],{"type":47,"value":2460},"    $results = $body['results'] ?? array();\n",{"type":41,"tag":1302,"props":2462,"children":2464},{"class":1304,"line":2463},133,[2465],{"type":41,"tag":1302,"props":2466,"children":2467},{},[2468],{"type":47,"value":2469},"    $cards   = array();\n",{"type":41,"tag":1302,"props":2471,"children":2473},{"class":1304,"line":2472},134,[2474],{"type":41,"tag":1302,"props":2475,"children":2476},{"emptyLinePlaceholder":1399},[2477],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2479,"children":2481},{"class":1304,"line":2480},135,[2482],{"type":41,"tag":1302,"props":2483,"children":2484},{},[2485],{"type":47,"value":2486},"    foreach ( array_slice( $results, 0, 10 ) as $item ) {\n",{"type":41,"tag":1302,"props":2488,"children":2490},{"class":1304,"line":2489},136,[2491],{"type":41,"tag":1302,"props":2492,"children":2493},{},[2494],{"type":47,"value":2495},"        $cards[] = array(\n",{"type":41,"tag":1302,"props":2497,"children":2499},{"class":1304,"line":2498},137,[2500],{"type":41,"tag":1302,"props":2501,"children":2502},{},[2503],{"type":47,"value":2504},"            'type'        => 'article',\n",{"type":41,"tag":1302,"props":2506,"children":2508},{"class":1304,"line":2507},138,[2509],{"type":41,"tag":1302,"props":2510,"children":2511},{},[2512],{"type":47,"value":2513},"            'source_type' => 'article',\n",{"type":41,"tag":1302,"props":2515,"children":2517},{"class":1304,"line":2516},139,[2518],{"type":41,"tag":1302,"props":2519,"children":2520},{},[2521],{"type":47,"value":2522},"            'origin'      => '{name}',\n",{"type":41,"tag":1302,"props":2524,"children":2526},{"class":1304,"line":2525},140,[2527],{"type":41,"tag":1302,"props":2528,"children":2529},{},[2530],{"type":47,"value":2531},"            'title'       => $item['title'] ?? '',\n",{"type":41,"tag":1302,"props":2533,"children":2535},{"class":1304,"line":2534},141,[2536],{"type":41,"tag":1302,"props":2537,"children":2538},{},[2539],{"type":47,"value":2540},"            'url'         => $item['url'] ?? '',\n",{"type":41,"tag":1302,"props":2542,"children":2544},{"class":1304,"line":2543},142,[2545],{"type":41,"tag":1302,"props":2546,"children":2547},{},[2548],{"type":47,"value":2549},"            'excerpt'     => $item['description'] ?? '',\n",{"type":41,"tag":1302,"props":2551,"children":2553},{"class":1304,"line":2552},143,[2554],{"type":41,"tag":1302,"props":2555,"children":2556},{},[2557],{"type":47,"value":2558},"            'content'     => $item['body'] ?? '',\n",{"type":41,"tag":1302,"props":2560,"children":2562},{"class":1304,"line":2561},144,[2563],{"type":41,"tag":1302,"props":2564,"children":2565},{},[2566],{"type":47,"value":2567},"            'domain'      => '{domain.com}',\n",{"type":41,"tag":1302,"props":2569,"children":2571},{"class":1304,"line":2570},145,[2572],{"type":41,"tag":1302,"props":2573,"children":2574},{},[2575],{"type":47,"value":2576},"            'author'      => $item['author'] ?? null,\n",{"type":41,"tag":1302,"props":2578,"children":2580},{"class":1304,"line":2579},146,[2581],{"type":41,"tag":1302,"props":2582,"children":2583},{},[2584],{"type":47,"value":2585},"            'date'        => $item['date'] ?? null,\n",{"type":41,"tag":1302,"props":2587,"children":2589},{"class":1304,"line":2588},147,[2590],{"type":41,"tag":1302,"props":2591,"children":2592},{},[2593],{"type":47,"value":2594},"            'image'       => $item['image'] ?? null,\n",{"type":41,"tag":1302,"props":2596,"children":2598},{"class":1304,"line":2597},148,[2599],{"type":41,"tag":1302,"props":2600,"children":2601},{},[2602],{"type":47,"value":2603},"            'source'      => '{name}',\n",{"type":41,"tag":1302,"props":2605,"children":2607},{"class":1304,"line":2606},149,[2608],{"type":41,"tag":1302,"props":2609,"children":2610},{},[2611],{"type":47,"value":2612},"        );\n",{"type":41,"tag":1302,"props":2614,"children":2615},{"class":1304,"line":22},[2616],{"type":41,"tag":1302,"props":2617,"children":2618},{},[2619],{"type":47,"value":1524},{"type":41,"tag":1302,"props":2621,"children":2623},{"class":1304,"line":2622},151,[2624],{"type":41,"tag":1302,"props":2625,"children":2626},{"emptyLinePlaceholder":1399},[2627],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2629,"children":2631},{"class":1304,"line":2630},152,[2632],{"type":41,"tag":1302,"props":2633,"children":2634},{},[2635],{"type":47,"value":2636},"    return $cards;\n",{"type":41,"tag":1302,"props":2638,"children":2640},{"class":1304,"line":2639},153,[2641],{"type":41,"tag":1302,"props":2642,"children":2643},{},[2644],{"type":47,"value":1463},{"type":41,"tag":2646,"props":2647,"children":2649},"h3",{"id":2648},"research-card-fields",[2650],{"type":47,"value":2651},"Research Card Fields",{"type":41,"tag":50,"props":2653,"children":2654},{},[2655,2657,2662],{"type":47,"value":2656},"Every card ",{"type":41,"tag":56,"props":2658,"children":2659},{},[2660],{"type":47,"value":2661},"must",{"type":47,"value":2663}," include:",{"type":41,"tag":71,"props":2665,"children":2666},{},[2667,2712,2723,2734],{"type":41,"tag":75,"props":2668,"children":2669},{},[2670,2676,2678,2684,2685,2691,2692,2698,2699,2705,2706],{"type":41,"tag":125,"props":2671,"children":2673},{"className":2672},[],[2674],{"type":47,"value":2675},"source_type",{"type":47,"value":2677}," — ",{"type":41,"tag":125,"props":2679,"children":2681},{"className":2680},[],[2682],{"type":47,"value":2683},"'article'",{"type":47,"value":909},{"type":41,"tag":125,"props":2686,"children":2688},{"className":2687},[],[2689],{"type":47,"value":2690},"'image'",{"type":47,"value":909},{"type":41,"tag":125,"props":2693,"children":2695},{"className":2694},[],[2696],{"type":47,"value":2697},"'video'",{"type":47,"value":909},{"type":41,"tag":125,"props":2700,"children":2702},{"className":2701},[],[2703],{"type":47,"value":2704},"'discussion'",{"type":47,"value":1006},{"type":41,"tag":125,"props":2707,"children":2709},{"className":2708},[],[2710],{"type":47,"value":2711},"'document'",{"type":41,"tag":75,"props":2713,"children":2714},{},[2715,2721],{"type":41,"tag":125,"props":2716,"children":2718},{"className":2717},[],[2719],{"type":47,"value":2720},"origin",{"type":47,"value":2722}," — identifies where this card came from (your source name)",{"type":41,"tag":75,"props":2724,"children":2725},{},[2726,2732],{"type":41,"tag":125,"props":2727,"children":2729},{"className":2728},[],[2730],{"type":47,"value":2731},"title",{"type":47,"value":2733}," — display title",{"type":41,"tag":75,"props":2735,"children":2736},{},[2737,2743],{"type":41,"tag":125,"props":2738,"children":2740},{"className":2739},[],[2741],{"type":47,"value":2742},"url",{"type":47,"value":2744}," — link to the original source",{"type":41,"tag":50,"props":2746,"children":2747},{},[2748,2750,2756,2757,2763,2764,2770,2771,2777,2778,2784,2785,2791,2792,2798,2799,2805],{"type":47,"value":2749},"Recommended: ",{"type":41,"tag":125,"props":2751,"children":2753},{"className":2752},[],[2754],{"type":47,"value":2755},"excerpt",{"type":47,"value":909},{"type":41,"tag":125,"props":2758,"children":2760},{"className":2759},[],[2761],{"type":47,"value":2762},"content",{"type":47,"value":909},{"type":41,"tag":125,"props":2765,"children":2767},{"className":2766},[],[2768],{"type":47,"value":2769},"domain",{"type":47,"value":909},{"type":41,"tag":125,"props":2772,"children":2774},{"className":2773},[],[2775],{"type":47,"value":2776},"author",{"type":47,"value":909},{"type":41,"tag":125,"props":2779,"children":2781},{"className":2780},[],[2782],{"type":47,"value":2783},"date",{"type":47,"value":909},{"type":41,"tag":125,"props":2786,"children":2788},{"className":2787},[],[2789],{"type":47,"value":2790},"image",{"type":47,"value":909},{"type":41,"tag":125,"props":2793,"children":2795},{"className":2794},[],[2796],{"type":47,"value":2797},"score",{"type":47,"value":909},{"type":41,"tag":125,"props":2800,"children":2802},{"className":2801},[],[2803],{"type":47,"value":2804},"source",{"type":47,"value":971},{"type":41,"tag":50,"props":2807,"children":2808},{},[2809,2814,2816,2821,2823,2828],{"type":41,"tag":56,"props":2810,"children":2811},{},[2812],{"type":47,"value":2813},"These fields are the card's identity.",{"type":47,"value":2815}," A stored source's id is derived from\nthe card — the URL when it has one, otherwise ",{"type":41,"tag":125,"props":2817,"children":2819},{"className":2818},[],[2820],{"type":47,"value":2731},{"type":47,"value":2822}," plus ",{"type":41,"tag":125,"props":2824,"children":2826},{"className":2825},[],[2827],{"type":47,"value":2762},{"type":47,"value":2829}," — so\nreturning the same card on a later run updates nothing and inserts nothing\nrather than adding a duplicate. Two consequences for your agent:",{"type":41,"tag":71,"props":2831,"children":2832},{},[2833,2845],{"type":41,"tag":75,"props":2834,"children":2835},{},[2836,2838,2843],{"type":47,"value":2837},"Return a stable ",{"type":41,"tag":125,"props":2839,"children":2841},{"className":2840},[],[2842],{"type":47,"value":2742},{"type":47,"value":2844}," for anything that has one. A URL that changes between\nruns (a cache-busting query param, a session id) forks into a new card\neach time.",{"type":41,"tag":75,"props":2846,"children":2847},{},[2848,2850,2855],{"type":47,"value":2849},"If your agent generates content rather than finding it, put the full body in\n",{"type":41,"tag":125,"props":2851,"children":2853},{"className":2852},[],[2854],{"type":47,"value":2762},{"type":47,"value":2856},". Cards with no URL are identified by title plus body, so two\ngenerated cards that differ only in a field you left out will collapse into\none and the second will be silently dropped.",{"type":41,"tag":50,"props":2858,"children":2859},{},[2860,2862,2868],{"type":47,"value":2861},"Optional grouping: if your agent returns related cards (e.g., an article + its comments), give them the same ",{"type":41,"tag":125,"props":2863,"children":2865},{"className":2864},[],[2866],{"type":47,"value":2867},"group_id",{"type":47,"value":2869}," string. The mood board will render them as a linked pair.",{"type":41,"tag":134,"props":2871,"children":2873},{"id":2872},"boilerplate-stage-capable",[2874],{"type":47,"value":2875},"Boilerplate: Stage-Capable",{"type":41,"tag":50,"props":2877,"children":2878},{},[2879],{"type":47,"value":2880},"Use this when the agent only runs as an AI-owned workflow stage.",{"type":41,"tag":1175,"props":2882,"children":2884},{"className":1294,"code":2883,"language":1296,"meta":1183,"style":1183},"\u003C?php\n\u002F**\n * Plugin Name: Workflow Agent: {Display Name}\n * Description: Stage-capable agent that {describes what it checks or rewrites}.\n * Version: 1.0.0\n * Requires Plugins: vip-workflows\n * Text Domain: workflow-agent-{name}\n *\n * @package WorkflowAgent{PascalName}\n *\u002F\n\ndeclare( strict_types=1 );\n\nnamespace WorkflowAgent{PascalName};\n\nuse VIPWorkflows\\Abilities\\Agents\\StageAgent;\n\nif ( ! defined( 'ABSPATH' ) ) {\n    exit;\n}\n\nadd_action( 'vip_workflows_register_abilities', __NAMESPACE__ . '\\register' );\nadd_action( 'vip_workflows_register_assistant_meta', __NAMESPACE__ . '\\register_agent_meta' );\n\nfunction register(): void {\n    if ( ! function_exists( 'vip_workflows_register_ability' ) || ! class_exists( StageAgent::class ) ) {\n        return;\n    }\n\n    vip_workflows_register_ability(\n        'workflow-agent-{name}\u002F{slug}',\n        array(\n            'label'               => __( '{Display Name}', 'workflow-agent-{name}' ),\n            'description'         => __( '{One-line description.}', 'workflow-agent-{name}' ),\n            'category'            => 'vip-workflows',\n            'input_schema'        => array(\n                'type'                 => 'object',\n                'additionalProperties' => false,\n                'properties'           => array(\n                    'post_id' => array(\n                        'type'        => 'integer',\n                        'description' => __( 'The post ID for this agent.', 'workflow-agent-{name}' ),\n                    ),\n                ),\n                'required'             => array( 'post_id' ),\n            ),\n            'output_schema'       => array(\n                'type'                 => 'object',\n                'additionalProperties' => false,\n                'required'             => array( 'status', 'summary' ),\n                'properties'           => array(\n                    'status'  => array(\n                        'type' => 'string',\n                        'enum' => array( 'pass', 'fail' ),\n                    ),\n                    'summary' => array( 'type' => 'string' ),\n                    'issues'  => array( 'type' => 'array' ),\n                ),\n            ),\n            'execute_callback'    => __NAMESPACE__ . '\\execute',\n            'permission_callback' => function () {\n                return current_user_can( 'edit_posts' );\n            },\n            'meta'                => array(\n                'type'                => 'agent',\n                'show_in_rest'        => true,\n                'show_in_commands'    => false,\n                'transition_eligible' => false,\n                'icon'                => 'search',\n                'supports'            => array( 'workflow', 'stage' ),\n                'stage_eligible'      => true,\n                'annotations'         => array(\n                    'readonly'    => true,\n                    'destructive' => false,\n                    'idempotent'  => true,\n                ),\n            ),\n        )\n    );\n}\n\nfunction register_agent_meta( $registry ): void {\n    $registry->register(\n        'workflow-agent-{name}',\n        array(\n            'label'        => __( '{Display Name}', 'workflow-agent-{name}' ),\n            'description'  => __( '{One-line description.}', 'workflow-agent-{name}' ),\n            'icon'         => 'search',\n            'ability_ids'  => array( 'workflow-agent-{name}\u002F{slug}' ),\n            'capabilities' => array( 'stage' ),\n        )\n    );\n}\n\nfunction execute( ?array $input = null ) {\n    $input   = $input ?? array();\n    $post_id = (int) ( $input['post_id'] ?? 0 );\n\n    if ( ! $post_id ) {\n        return new \\WP_Error( 'missing_post_id', __( 'A post_id is required.', 'workflow-agent-{name}' ) );\n    }\n\n    $post = StageAgent::read_post( $post_id );\n    if ( is_wp_error( $post ) ) {\n        return $post;\n    }\n\n    \u002F\u002F Build your prompt or deterministic check from $post['title'] and $post['content'].\n    \u002F\u002F Return StageAgent::result( 'pass', '...' ) or StageAgent::result( 'fail', '...', array( 'issues' => $issues ) ).\n}\n",[2885],{"type":41,"tag":125,"props":2886,"children":2887},{"__ignoreMap":1183},[2888,2895,2902,2909,2917,2924,2931,2938,2945,2952,2959,2966,2973,2980,2987,2994,3002,3009,3016,3023,3030,3037,3045,3053,3060,3067,3075,3082,3089,3096,3103,3110,3117,3124,3132,3140,3147,3155,3163,3171,3179,3187,3195,3203,3210,3218,3225,3232,3239,3246,3254,3261,3269,3277,3285,3292,3299,3307,3314,3321,3328,3335,3342,3349,3356,3364,3372,3380,3388,3396,3404,3412,3420,3428,3436,3444,3451,3458,3465,3472,3479,3486,3494,3502,3510,3517,3525,3533,3541,3549,3557,3564,3571,3578,3585,3593,3601,3609,3616,3624,3632,3639,3646,3654,3662,3670,3677,3684,3692,3700],{"type":41,"tag":1302,"props":2889,"children":2890},{"class":1304,"line":1305},[2891],{"type":41,"tag":1302,"props":2892,"children":2893},{},[2894],{"type":47,"value":1311},{"type":41,"tag":1302,"props":2896,"children":2897},{"class":1304,"line":1314},[2898],{"type":41,"tag":1302,"props":2899,"children":2900},{},[2901],{"type":47,"value":1320},{"type":41,"tag":1302,"props":2903,"children":2904},{"class":1304,"line":1323},[2905],{"type":41,"tag":1302,"props":2906,"children":2907},{},[2908],{"type":47,"value":1329},{"type":41,"tag":1302,"props":2910,"children":2911},{"class":1304,"line":1332},[2912],{"type":41,"tag":1302,"props":2913,"children":2914},{},[2915],{"type":47,"value":2916}," * Description: Stage-capable agent that {describes what it checks or rewrites}.\n",{"type":41,"tag":1302,"props":2918,"children":2919},{"class":1304,"line":1341},[2920],{"type":41,"tag":1302,"props":2921,"children":2922},{},[2923],{"type":47,"value":1347},{"type":41,"tag":1302,"props":2925,"children":2926},{"class":1304,"line":1350},[2927],{"type":41,"tag":1302,"props":2928,"children":2929},{},[2930],{"type":47,"value":1356},{"type":41,"tag":1302,"props":2932,"children":2933},{"class":1304,"line":1359},[2934],{"type":41,"tag":1302,"props":2935,"children":2936},{},[2937],{"type":47,"value":1365},{"type":41,"tag":1302,"props":2939,"children":2940},{"class":1304,"line":1368},[2941],{"type":41,"tag":1302,"props":2942,"children":2943},{},[2944],{"type":47,"value":1374},{"type":41,"tag":1302,"props":2946,"children":2947},{"class":1304,"line":1377},[2948],{"type":41,"tag":1302,"props":2949,"children":2950},{},[2951],{"type":47,"value":1383},{"type":41,"tag":1302,"props":2953,"children":2954},{"class":1304,"line":1386},[2955],{"type":41,"tag":1302,"props":2956,"children":2957},{},[2958],{"type":47,"value":1392},{"type":41,"tag":1302,"props":2960,"children":2961},{"class":1304,"line":1395},[2962],{"type":41,"tag":1302,"props":2963,"children":2964},{"emptyLinePlaceholder":1399},[2965],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2967,"children":2968},{"class":1304,"line":1405},[2969],{"type":41,"tag":1302,"props":2970,"children":2971},{},[2972],{"type":47,"value":1411},{"type":41,"tag":1302,"props":2974,"children":2975},{"class":1304,"line":1414},[2976],{"type":41,"tag":1302,"props":2977,"children":2978},{"emptyLinePlaceholder":1399},[2979],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2981,"children":2982},{"class":1304,"line":1422},[2983],{"type":41,"tag":1302,"props":2984,"children":2985},{},[2986],{"type":47,"value":1428},{"type":41,"tag":1302,"props":2988,"children":2989},{"class":1304,"line":1431},[2990],{"type":41,"tag":1302,"props":2991,"children":2992},{"emptyLinePlaceholder":1399},[2993],{"type":47,"value":1402},{"type":41,"tag":1302,"props":2995,"children":2996},{"class":1304,"line":1439},[2997],{"type":41,"tag":1302,"props":2998,"children":2999},{},[3000],{"type":47,"value":3001},"use VIPWorkflows\\Abilities\\Agents\\StageAgent;\n",{"type":41,"tag":1302,"props":3003,"children":3004},{"class":1304,"line":1448},[3005],{"type":41,"tag":1302,"props":3006,"children":3007},{"emptyLinePlaceholder":1399},[3008],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3010,"children":3011},{"class":1304,"line":1457},[3012],{"type":41,"tag":1302,"props":3013,"children":3014},{},[3015],{"type":47,"value":1445},{"type":41,"tag":1302,"props":3017,"children":3018},{"class":1304,"line":1466},[3019],{"type":41,"tag":1302,"props":3020,"children":3021},{},[3022],{"type":47,"value":1454},{"type":41,"tag":1302,"props":3024,"children":3025},{"class":1304,"line":1474},[3026],{"type":41,"tag":1302,"props":3027,"children":3028},{},[3029],{"type":47,"value":1463},{"type":41,"tag":1302,"props":3031,"children":3032},{"class":1304,"line":1483},[3033],{"type":41,"tag":1302,"props":3034,"children":3035},{"emptyLinePlaceholder":1399},[3036],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3038,"children":3039},{"class":1304,"line":1491},[3040],{"type":41,"tag":1302,"props":3041,"children":3042},{},[3043],{"type":47,"value":3044},"add_action( 'vip_workflows_register_abilities', __NAMESPACE__ . '\\register' );\n",{"type":41,"tag":1302,"props":3046,"children":3047},{"class":1304,"line":1500},[3048],{"type":41,"tag":1302,"props":3049,"children":3050},{},[3051],{"type":47,"value":3052},"add_action( 'vip_workflows_register_assistant_meta', __NAMESPACE__ . '\\register_agent_meta' );\n",{"type":41,"tag":1302,"props":3054,"children":3055},{"class":1304,"line":1509},[3056],{"type":41,"tag":1302,"props":3057,"children":3058},{"emptyLinePlaceholder":1399},[3059],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3061,"children":3062},{"class":1304,"line":1518},[3063],{"type":41,"tag":1302,"props":3064,"children":3065},{},[3066],{"type":47,"value":1497},{"type":41,"tag":1302,"props":3068,"children":3069},{"class":1304,"line":1527},[3070],{"type":41,"tag":1302,"props":3071,"children":3072},{},[3073],{"type":47,"value":3074},"    if ( ! function_exists( 'vip_workflows_register_ability' ) || ! class_exists( StageAgent::class ) ) {\n",{"type":41,"tag":1302,"props":3076,"children":3077},{"class":1304,"line":1535},[3078],{"type":41,"tag":1302,"props":3079,"children":3080},{},[3081],{"type":47,"value":1515},{"type":41,"tag":1302,"props":3083,"children":3084},{"class":1304,"line":1544},[3085],{"type":41,"tag":1302,"props":3086,"children":3087},{},[3088],{"type":47,"value":1524},{"type":41,"tag":1302,"props":3090,"children":3091},{"class":1304,"line":1553},[3092],{"type":41,"tag":1302,"props":3093,"children":3094},{"emptyLinePlaceholder":1399},[3095],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3097,"children":3098},{"class":1304,"line":1562},[3099],{"type":41,"tag":1302,"props":3100,"children":3101},{},[3102],{"type":47,"value":1541},{"type":41,"tag":1302,"props":3104,"children":3105},{"class":1304,"line":1571},[3106],{"type":41,"tag":1302,"props":3107,"children":3108},{},[3109],{"type":47,"value":1550},{"type":41,"tag":1302,"props":3111,"children":3112},{"class":1304,"line":1580},[3113],{"type":41,"tag":1302,"props":3114,"children":3115},{},[3116],{"type":47,"value":1559},{"type":41,"tag":1302,"props":3118,"children":3119},{"class":1304,"line":1589},[3120],{"type":41,"tag":1302,"props":3121,"children":3122},{},[3123],{"type":47,"value":1568},{"type":41,"tag":1302,"props":3125,"children":3126},{"class":1304,"line":1598},[3127],{"type":41,"tag":1302,"props":3128,"children":3129},{},[3130],{"type":47,"value":3131},"            'description'         => __( '{One-line description.}', 'workflow-agent-{name}' ),\n",{"type":41,"tag":1302,"props":3133,"children":3134},{"class":1304,"line":1607},[3135],{"type":41,"tag":1302,"props":3136,"children":3137},{},[3138],{"type":47,"value":3139},"            'category'            => 'vip-workflows',\n",{"type":41,"tag":1302,"props":3141,"children":3142},{"class":1304,"line":1616},[3143],{"type":41,"tag":1302,"props":3144,"children":3145},{},[3146],{"type":47,"value":1595},{"type":41,"tag":1302,"props":3148,"children":3149},{"class":1304,"line":1625},[3150],{"type":41,"tag":1302,"props":3151,"children":3152},{},[3153],{"type":47,"value":3154},"                'type'                 => 'object',\n",{"type":41,"tag":1302,"props":3156,"children":3157},{"class":1304,"line":26},[3158],{"type":41,"tag":1302,"props":3159,"children":3160},{},[3161],{"type":47,"value":3162},"                'additionalProperties' => false,\n",{"type":41,"tag":1302,"props":3164,"children":3165},{"class":1304,"line":1642},[3166],{"type":41,"tag":1302,"props":3167,"children":3168},{},[3169],{"type":47,"value":3170},"                'properties'           => array(\n",{"type":41,"tag":1302,"props":3172,"children":3173},{"class":1304,"line":1651},[3174],{"type":41,"tag":1302,"props":3175,"children":3176},{},[3177],{"type":47,"value":3178},"                    'post_id' => array(\n",{"type":41,"tag":1302,"props":3180,"children":3181},{"class":1304,"line":1660},[3182],{"type":41,"tag":1302,"props":3183,"children":3184},{},[3185],{"type":47,"value":3186},"                        'type'        => 'integer',\n",{"type":41,"tag":1302,"props":3188,"children":3189},{"class":1304,"line":1669},[3190],{"type":41,"tag":1302,"props":3191,"children":3192},{},[3193],{"type":47,"value":3194},"                        'description' => __( 'The post ID for this agent.', 'workflow-agent-{name}' ),\n",{"type":41,"tag":1302,"props":3196,"children":3197},{"class":1304,"line":1678},[3198],{"type":41,"tag":1302,"props":3199,"children":3200},{},[3201],{"type":47,"value":3202},"                    ),\n",{"type":41,"tag":1302,"props":3204,"children":3205},{"class":1304,"line":1687},[3206],{"type":41,"tag":1302,"props":3207,"children":3208},{},[3209],{"type":47,"value":1666},{"type":41,"tag":1302,"props":3211,"children":3212},{"class":1304,"line":1696},[3213],{"type":41,"tag":1302,"props":3214,"children":3215},{},[3216],{"type":47,"value":3217},"                'required'             => array( 'post_id' ),\n",{"type":41,"tag":1302,"props":3219,"children":3220},{"class":1304,"line":1704},[3221],{"type":41,"tag":1302,"props":3222,"children":3223},{},[3224],{"type":47,"value":1684},{"type":41,"tag":1302,"props":3226,"children":3227},{"class":1304,"line":1712},[3228],{"type":41,"tag":1302,"props":3229,"children":3230},{},[3231],{"type":47,"value":1693},{"type":41,"tag":1302,"props":3233,"children":3234},{"class":1304,"line":1721},[3235],{"type":41,"tag":1302,"props":3236,"children":3237},{},[3238],{"type":47,"value":3154},{"type":41,"tag":1302,"props":3240,"children":3241},{"class":1304,"line":1730},[3242],{"type":41,"tag":1302,"props":3243,"children":3244},{},[3245],{"type":47,"value":3162},{"type":41,"tag":1302,"props":3247,"children":3248},{"class":1304,"line":1738},[3249],{"type":41,"tag":1302,"props":3250,"children":3251},{},[3252],{"type":47,"value":3253},"                'required'             => array( 'status', 'summary' ),\n",{"type":41,"tag":1302,"props":3255,"children":3256},{"class":1304,"line":1746},[3257],{"type":41,"tag":1302,"props":3258,"children":3259},{},[3260],{"type":47,"value":3170},{"type":41,"tag":1302,"props":3262,"children":3263},{"class":1304,"line":1755},[3264],{"type":41,"tag":1302,"props":3265,"children":3266},{},[3267],{"type":47,"value":3268},"                    'status'  => array(\n",{"type":41,"tag":1302,"props":3270,"children":3271},{"class":1304,"line":1764},[3272],{"type":41,"tag":1302,"props":3273,"children":3274},{},[3275],{"type":47,"value":3276},"                        'type' => 'string',\n",{"type":41,"tag":1302,"props":3278,"children":3279},{"class":1304,"line":1773},[3280],{"type":41,"tag":1302,"props":3281,"children":3282},{},[3283],{"type":47,"value":3284},"                        'enum' => array( 'pass', 'fail' ),\n",{"type":41,"tag":1302,"props":3286,"children":3287},{"class":1304,"line":1782},[3288],{"type":41,"tag":1302,"props":3289,"children":3290},{},[3291],{"type":47,"value":3202},{"type":41,"tag":1302,"props":3293,"children":3294},{"class":1304,"line":1791},[3295],{"type":41,"tag":1302,"props":3296,"children":3297},{},[3298],{"type":47,"value":1727},{"type":41,"tag":1302,"props":3300,"children":3301},{"class":1304,"line":1800},[3302],{"type":41,"tag":1302,"props":3303,"children":3304},{},[3305],{"type":47,"value":3306},"                    'issues'  => array( 'type' => 'array' ),\n",{"type":41,"tag":1302,"props":3308,"children":3309},{"class":1304,"line":1809},[3310],{"type":41,"tag":1302,"props":3311,"children":3312},{},[3313],{"type":47,"value":1666},{"type":41,"tag":1302,"props":3315,"children":3316},{"class":1304,"line":1818},[3317],{"type":41,"tag":1302,"props":3318,"children":3319},{},[3320],{"type":47,"value":1684},{"type":41,"tag":1302,"props":3322,"children":3323},{"class":1304,"line":1827},[3324],{"type":41,"tag":1302,"props":3325,"children":3326},{},[3327],{"type":47,"value":1752},{"type":41,"tag":1302,"props":3329,"children":3330},{"class":1304,"line":1836},[3331],{"type":41,"tag":1302,"props":3332,"children":3333},{},[3334],{"type":47,"value":1761},{"type":41,"tag":1302,"props":3336,"children":3337},{"class":1304,"line":1845},[3338],{"type":41,"tag":1302,"props":3339,"children":3340},{},[3341],{"type":47,"value":1770},{"type":41,"tag":1302,"props":3343,"children":3344},{"class":1304,"line":1854},[3345],{"type":41,"tag":1302,"props":3346,"children":3347},{},[3348],{"type":47,"value":1779},{"type":41,"tag":1302,"props":3350,"children":3351},{"class":1304,"line":1863},[3352],{"type":41,"tag":1302,"props":3353,"children":3354},{},[3355],{"type":47,"value":1788},{"type":41,"tag":1302,"props":3357,"children":3358},{"class":1304,"line":1872},[3359],{"type":41,"tag":1302,"props":3360,"children":3361},{},[3362],{"type":47,"value":3363},"                'type'                => 'agent',\n",{"type":41,"tag":1302,"props":3365,"children":3366},{"class":1304,"line":1881},[3367],{"type":41,"tag":1302,"props":3368,"children":3369},{},[3370],{"type":47,"value":3371},"                'show_in_rest'        => true,\n",{"type":41,"tag":1302,"props":3373,"children":3374},{"class":1304,"line":1890},[3375],{"type":41,"tag":1302,"props":3376,"children":3377},{},[3378],{"type":47,"value":3379},"                'show_in_commands'    => false,\n",{"type":41,"tag":1302,"props":3381,"children":3382},{"class":1304,"line":1899},[3383],{"type":41,"tag":1302,"props":3384,"children":3385},{},[3386],{"type":47,"value":3387},"                'transition_eligible' => false,\n",{"type":41,"tag":1302,"props":3389,"children":3390},{"class":1304,"line":1908},[3391],{"type":41,"tag":1302,"props":3392,"children":3393},{},[3394],{"type":47,"value":3395},"                'icon'                => 'search',\n",{"type":41,"tag":1302,"props":3397,"children":3398},{"class":1304,"line":1917},[3399],{"type":41,"tag":1302,"props":3400,"children":3401},{},[3402],{"type":47,"value":3403},"                'supports'            => array( 'workflow', 'stage' ),\n",{"type":41,"tag":1302,"props":3405,"children":3406},{"class":1304,"line":1926},[3407],{"type":41,"tag":1302,"props":3408,"children":3409},{},[3410],{"type":47,"value":3411},"                'stage_eligible'      => true,\n",{"type":41,"tag":1302,"props":3413,"children":3414},{"class":1304,"line":1935},[3415],{"type":41,"tag":1302,"props":3416,"children":3417},{},[3418],{"type":47,"value":3419},"                'annotations'         => array(\n",{"type":41,"tag":1302,"props":3421,"children":3422},{"class":1304,"line":1944},[3423],{"type":41,"tag":1302,"props":3424,"children":3425},{},[3426],{"type":47,"value":3427},"                    'readonly'    => true,\n",{"type":41,"tag":1302,"props":3429,"children":3430},{"class":1304,"line":1953},[3431],{"type":41,"tag":1302,"props":3432,"children":3433},{},[3434],{"type":47,"value":3435},"                    'destructive' => false,\n",{"type":41,"tag":1302,"props":3437,"children":3438},{"class":1304,"line":1962},[3439],{"type":41,"tag":1302,"props":3440,"children":3441},{},[3442],{"type":47,"value":3443},"                    'idempotent'  => true,\n",{"type":41,"tag":1302,"props":3445,"children":3446},{"class":1304,"line":1971},[3447],{"type":41,"tag":1302,"props":3448,"children":3449},{},[3450],{"type":47,"value":1666},{"type":41,"tag":1302,"props":3452,"children":3453},{"class":1304,"line":1979},[3454],{"type":41,"tag":1302,"props":3455,"children":3456},{},[3457],{"type":47,"value":1684},{"type":41,"tag":1302,"props":3459,"children":3460},{"class":1304,"line":1988},[3461],{"type":41,"tag":1302,"props":3462,"children":3463},{},[3464],{"type":47,"value":2020},{"type":41,"tag":1302,"props":3466,"children":3467},{"class":1304,"line":1997},[3468],{"type":41,"tag":1302,"props":3469,"children":3470},{},[3471],{"type":47,"value":2029},{"type":41,"tag":1302,"props":3473,"children":3474},{"class":1304,"line":2006},[3475],{"type":41,"tag":1302,"props":3476,"children":3477},{},[3478],{"type":47,"value":1463},{"type":41,"tag":1302,"props":3480,"children":3481},{"class":1304,"line":2014},[3482],{"type":41,"tag":1302,"props":3483,"children":3484},{"emptyLinePlaceholder":1399},[3485],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3487,"children":3488},{"class":1304,"line":2023},[3489],{"type":41,"tag":1302,"props":3490,"children":3491},{},[3492],{"type":47,"value":3493},"function register_agent_meta( $registry ): void {\n",{"type":41,"tag":1302,"props":3495,"children":3496},{"class":1304,"line":2032},[3497],{"type":41,"tag":1302,"props":3498,"children":3499},{},[3500],{"type":47,"value":3501},"    $registry->register(\n",{"type":41,"tag":1302,"props":3503,"children":3504},{"class":1304,"line":2040},[3505],{"type":41,"tag":1302,"props":3506,"children":3507},{},[3508],{"type":47,"value":3509},"        'workflow-agent-{name}',\n",{"type":41,"tag":1302,"props":3511,"children":3512},{"class":1304,"line":2048},[3513],{"type":41,"tag":1302,"props":3514,"children":3515},{},[3516],{"type":47,"value":1559},{"type":41,"tag":1302,"props":3518,"children":3519},{"class":1304,"line":2056},[3520],{"type":41,"tag":1302,"props":3521,"children":3522},{},[3523],{"type":47,"value":3524},"            'label'        => __( '{Display Name}', 'workflow-agent-{name}' ),\n",{"type":41,"tag":1302,"props":3526,"children":3527},{"class":1304,"line":2065},[3528],{"type":41,"tag":1302,"props":3529,"children":3530},{},[3531],{"type":47,"value":3532},"            'description'  => __( '{One-line description.}', 'workflow-agent-{name}' ),\n",{"type":41,"tag":1302,"props":3534,"children":3535},{"class":1304,"line":2073},[3536],{"type":41,"tag":1302,"props":3537,"children":3538},{},[3539],{"type":47,"value":3540},"            'icon'         => 'search',\n",{"type":41,"tag":1302,"props":3542,"children":3543},{"class":1304,"line":2082},[3544],{"type":41,"tag":1302,"props":3545,"children":3546},{},[3547],{"type":47,"value":3548},"            'ability_ids'  => array( 'workflow-agent-{name}\u002F{slug}' ),\n",{"type":41,"tag":1302,"props":3550,"children":3551},{"class":1304,"line":2091},[3552],{"type":41,"tag":1302,"props":3553,"children":3554},{},[3555],{"type":47,"value":3556},"            'capabilities' => array( 'stage' ),\n",{"type":41,"tag":1302,"props":3558,"children":3559},{"class":1304,"line":2100},[3560],{"type":41,"tag":1302,"props":3561,"children":3562},{},[3563],{"type":47,"value":2020},{"type":41,"tag":1302,"props":3565,"children":3566},{"class":1304,"line":2108},[3567],{"type":41,"tag":1302,"props":3568,"children":3569},{},[3570],{"type":47,"value":2029},{"type":41,"tag":1302,"props":3572,"children":3573},{"class":1304,"line":2117},[3574],{"type":41,"tag":1302,"props":3575,"children":3576},{},[3577],{"type":47,"value":1463},{"type":41,"tag":1302,"props":3579,"children":3580},{"class":1304,"line":2126},[3581],{"type":41,"tag":1302,"props":3582,"children":3583},{"emptyLinePlaceholder":1399},[3584],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3586,"children":3587},{"class":1304,"line":2134},[3588],{"type":41,"tag":1302,"props":3589,"children":3590},{},[3591],{"type":47,"value":3592},"function execute( ?array $input = null ) {\n",{"type":41,"tag":1302,"props":3594,"children":3595},{"class":1304,"line":2143},[3596],{"type":41,"tag":1302,"props":3597,"children":3598},{},[3599],{"type":47,"value":3600},"    $input   = $input ?? array();\n",{"type":41,"tag":1302,"props":3602,"children":3603},{"class":1304,"line":2152},[3604],{"type":41,"tag":1302,"props":3605,"children":3606},{},[3607],{"type":47,"value":3608},"    $post_id = (int) ( $input['post_id'] ?? 0 );\n",{"type":41,"tag":1302,"props":3610,"children":3611},{"class":1304,"line":2160},[3612],{"type":41,"tag":1302,"props":3613,"children":3614},{"emptyLinePlaceholder":1399},[3615],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3617,"children":3618},{"class":1304,"line":2169},[3619],{"type":41,"tag":1302,"props":3620,"children":3621},{},[3622],{"type":47,"value":3623},"    if ( ! $post_id ) {\n",{"type":41,"tag":1302,"props":3625,"children":3626},{"class":1304,"line":2178},[3627],{"type":41,"tag":1302,"props":3628,"children":3629},{},[3630],{"type":47,"value":3631},"        return new \\WP_Error( 'missing_post_id', __( 'A post_id is required.', 'workflow-agent-{name}' ) );\n",{"type":41,"tag":1302,"props":3633,"children":3634},{"class":1304,"line":2187},[3635],{"type":41,"tag":1302,"props":3636,"children":3637},{},[3638],{"type":47,"value":1524},{"type":41,"tag":1302,"props":3640,"children":3641},{"class":1304,"line":2196},[3642],{"type":41,"tag":1302,"props":3643,"children":3644},{"emptyLinePlaceholder":1399},[3645],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3647,"children":3648},{"class":1304,"line":2205},[3649],{"type":41,"tag":1302,"props":3650,"children":3651},{},[3652],{"type":47,"value":3653},"    $post = StageAgent::read_post( $post_id );\n",{"type":41,"tag":1302,"props":3655,"children":3656},{"class":1304,"line":2214},[3657],{"type":41,"tag":1302,"props":3658,"children":3659},{},[3660],{"type":47,"value":3661},"    if ( is_wp_error( $post ) ) {\n",{"type":41,"tag":1302,"props":3663,"children":3664},{"class":1304,"line":2223},[3665],{"type":41,"tag":1302,"props":3666,"children":3667},{},[3668],{"type":47,"value":3669},"        return $post;\n",{"type":41,"tag":1302,"props":3671,"children":3672},{"class":1304,"line":2231},[3673],{"type":41,"tag":1302,"props":3674,"children":3675},{},[3676],{"type":47,"value":1524},{"type":41,"tag":1302,"props":3678,"children":3679},{"class":1304,"line":2239},[3680],{"type":41,"tag":1302,"props":3681,"children":3682},{"emptyLinePlaceholder":1399},[3683],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3685,"children":3686},{"class":1304,"line":2248},[3687],{"type":41,"tag":1302,"props":3688,"children":3689},{},[3690],{"type":47,"value":3691},"    \u002F\u002F Build your prompt or deterministic check from $post['title'] and $post['content'].\n",{"type":41,"tag":1302,"props":3693,"children":3694},{"class":1304,"line":2257},[3695],{"type":41,"tag":1302,"props":3696,"children":3697},{},[3698],{"type":47,"value":3699},"    \u002F\u002F Return StageAgent::result( 'pass', '...' ) or StageAgent::result( 'fail', '...', array( 'issues' => $issues ) ).\n",{"type":41,"tag":1302,"props":3701,"children":3702},{"class":1304,"line":2266},[3703],{"type":41,"tag":1302,"props":3704,"children":3705},{},[3706],{"type":47,"value":1463},{"type":41,"tag":50,"props":3708,"children":3709},{},[3710,3712,3718,3719,3725],{"type":47,"value":3711},"The unified agent REST entry will include ",{"type":41,"tag":125,"props":3713,"children":3715},{"className":3714},[],[3716],{"type":47,"value":3717},"capabilities: [ 'stage' ]",{"type":47,"value":1106},{"type":41,"tag":125,"props":3720,"children":3722},{"className":3721},[],[3723],{"type":47,"value":3724},"available_in_ai_stage: true",{"type":47,"value":3726}," when the ability is registered and stage-eligible.",{"type":41,"tag":134,"props":3728,"children":3730},{"id":3729},"boilerplate-discovery-only",[3731],{"type":47,"value":3732},"Boilerplate: Discovery-Only",{"type":41,"tag":50,"props":3734,"children":3735},{},[3736],{"type":47,"value":3737},"Use this when the agent only surfaces prompts on the landing page.",{"type":41,"tag":1175,"props":3739,"children":3741},{"className":1294,"code":3740,"language":1296,"meta":1183,"style":1183},"\u003C?php\n\u002F**\n * Plugin Name: Workflow Discovery: {Display Name}\n * Description: Story discovery provider that surfaces prompts from {data source}.\n * Version: 1.0.0\n * Requires Plugins: vip-workflows\n * Text Domain: workflow-discovery-{name}\n *\n * @package WorkflowDiscovery{PascalName}\n *\u002F\n\ndeclare( strict_types=1 );\n\nnamespace WorkflowDiscovery{PascalName};\n\nif ( ! defined( 'ABSPATH' ) ) {\n    exit;\n}\n\nadd_action( 'vip_workflows_register_discovery_providers', __NAMESPACE__ . '\\register' );\n\nfunction register( $registry ): void {\n    $registry->register( '{provider-slug}', array(\n        'label'       => __( '{Display Name}', 'workflow-discovery-{name}' ),\n        'description' => __( '{One-line description of what this provider surfaces.}', 'workflow-discovery-{name}' ),\n        'icon'        => 'search',\n        'features'    => array( 'recommend', 'search' ), \u002F\u002F keep only what you implement\n        'callbacks'   => array(\n            'recommend' => __NAMESPACE__ . '\\get_recommendations', \u002F\u002F required if 'recommend' in features\n            'search'    => __NAMESPACE__ . '\\search',              \u002F\u002F required if 'search' in features\n            'filters'   => __NAMESPACE__ . '\\get_filters',         \u002F\u002F required if 'search' in features\n            'seed'      => __NAMESPACE__ . '\\generate_seed',       \u002F\u002F always required\n        ),\n        \u002F\u002F Uncomment if credentials are needed. See the Availability section below\n        \u002F\u002F for the callback body.\n        \u002F\u002F 'availability_callback' => __NAMESPACE__ . '\\check_availability',\n    ) );\n}\n\n\u002F**\n * Return curated prompts for the landing page.\n *\n * Called on page load with the provider's saved settings.\n * Return up to 6 prompts. Cache aggressively (see Caching section).\n *\n * @param array $config Provider settings (categories, regions, etc.).\n * @return array Array of story prompt arrays.\n *\u002F\nfunction get_recommendations( array $config ): array {\n    $response = wp_remote_get( 'https:\u002F\u002Fapi.example.com\u002Fupcoming', array( 'timeout' => 10 ) );\n\n    if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {\n        return array();\n    }\n\n    $body    = json_decode( wp_remote_retrieve_body( $response ), true );\n    $results = $body['items'] ?? array();\n\n    return array_map( __NAMESPACE__ . '\\normalize_prompt', array_slice( $results, 0, 6 ) );\n}\n\n\u002F**\n * Search for prompts matching user criteria.\n *\n * @param array $params { text: string, filters: array\u003Cstring, mixed> }\n * @return array Array of story prompt arrays.\n *\u002F\nfunction search( array $params ): array {\n    $text    = $params['text'] ?? '';\n    $filters = $params['filters'] ?? array();\n\n    $url      = add_query_arg( array( 'q' => $text ), 'https:\u002F\u002Fapi.example.com\u002Fsearch' );\n    $response = wp_remote_get( $url, array( 'timeout' => 10 ) );\n\n    if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {\n        return array();\n    }\n\n    $body    = json_decode( wp_remote_retrieve_body( $response ), true );\n    $results = $body['items'] ?? array();\n\n    return array_map( __NAMESPACE__ . '\\normalize_prompt', $results );\n}\n\n\u002F**\n * Return search filter definitions for the modal UI.\n *\n * Supported types: 'select', 'multi_select', 'date_range'.\n * Return an empty array if the provider has no filters but supports search.\n *\u002F\nfunction get_filters(): array {\n    return array(\n        array(\n            'key'     => 'category',\n            'label'   => __( 'Category', 'workflow-discovery-{name}' ),\n            'type'    => 'select',\n            'options' => array(\n                array( 'value' => 'all', 'label' => 'All categories' ),\n            ),\n        ),\n        \u002F\u002F array(\n        \u002F\u002F     'key'     => 'date_range',\n        \u002F\u002F     'label'   => __( 'Date range', 'workflow-discovery-{name}' ),\n        \u002F\u002F     'type'    => 'date_range',\n        \u002F\u002F     'default' => array( 'from' => 'today', 'to' => '+90 days' ),\n        \u002F\u002F ),\n    );\n}\n\n\u002F**\n * Compose a seed string from a selected prompt.\n *\n * Called when an editor clicks a prompt card. The returned string becomes\n * the seed for a new ideation project. Include the most relevant context\n * your data source provides.\n *\u002F\nfunction generate_seed( array $prompt ): string {\n    $parts = array( $prompt['title'] );\n\n    if ( ! empty( $prompt['description'] ) ) {\n        $parts[] = $prompt['description'];\n    }\n    if ( ! empty( $prompt['date'] ) ) {\n        $parts[] = sprintf( 'Scheduled for %s.', date( 'F j, Y', strtotime( $prompt['date'] ) ) );\n    }\n    if ( ! empty( $prompt['tags'] ) ) {\n        $parts[] = sprintf( 'Topics: %s.', implode( ', ', $prompt['tags'] ) );\n    }\n\n    return implode( ' ', $parts );\n}\n\nfunction normalize_prompt( array $item ): array {\n    return array(\n        'id'          => '{provider-slug}-' . ( $item['id'] ?? '' ),\n        'provider'    => '{provider-slug}',\n        'title'       => $item['title'] ?? '',\n        'description' => $item['description'] ?? '',\n        'url'         => $item['url'] ?? '',\n        'date'        => $item['date'] ?? null,\n        'date_end'    => $item['date_end'] ?? null,\n        'tags'        => $item['tags'] ?? array(),\n        'importance'  => $item['importance'] ?? 'normal',\n        'meta'        => $item['meta'] ?? array(),\n    );\n}\n",[3742],{"type":41,"tag":125,"props":3743,"children":3744},{"__ignoreMap":1183},[3745,3752,3759,3767,3775,3782,3789,3797,3804,3812,3819,3826,3833,3840,3848,3855,3862,3869,3876,3883,3891,3898,3906,3914,3922,3930,3938,3951,3959,3972,3985,3998,4011,4019,4027,4035,4043,4051,4058,4065,4072,4080,4087,4095,4103,4110,4118,4126,4133,4141,4149,4156,4163,4170,4177,4184,4191,4199,4206,4214,4221,4228,4235,4243,4250,4258,4265,4272,4280,4288,4296,4303,4311,4318,4325,4332,4339,4346,4353,4360,4367,4374,4382,4389,4396,4403,4411,4418,4426,4434,4441,4449,4456,4463,4471,4479,4487,4495,4503,4510,4517,4525,4533,4541,4549,4557,4565,4572,4579,4586,4593,4601,4608,4616,4624,4632,4639,4647,4655,4662,4670,4678,4685,4693,4701,4708,4716,4724,4731,4738,4746,4753,4760,4768,4775,4783,4791,4799,4807,4815,4823,4831,4839,4847,4855,4862],{"type":41,"tag":1302,"props":3746,"children":3747},{"class":1304,"line":1305},[3748],{"type":41,"tag":1302,"props":3749,"children":3750},{},[3751],{"type":47,"value":1311},{"type":41,"tag":1302,"props":3753,"children":3754},{"class":1304,"line":1314},[3755],{"type":41,"tag":1302,"props":3756,"children":3757},{},[3758],{"type":47,"value":1320},{"type":41,"tag":1302,"props":3760,"children":3761},{"class":1304,"line":1323},[3762],{"type":41,"tag":1302,"props":3763,"children":3764},{},[3765],{"type":47,"value":3766}," * Plugin Name: Workflow Discovery: {Display Name}\n",{"type":41,"tag":1302,"props":3768,"children":3769},{"class":1304,"line":1332},[3770],{"type":41,"tag":1302,"props":3771,"children":3772},{},[3773],{"type":47,"value":3774}," * Description: Story discovery provider that surfaces prompts from {data source}.\n",{"type":41,"tag":1302,"props":3776,"children":3777},{"class":1304,"line":1341},[3778],{"type":41,"tag":1302,"props":3779,"children":3780},{},[3781],{"type":47,"value":1347},{"type":41,"tag":1302,"props":3783,"children":3784},{"class":1304,"line":1350},[3785],{"type":41,"tag":1302,"props":3786,"children":3787},{},[3788],{"type":47,"value":1356},{"type":41,"tag":1302,"props":3790,"children":3791},{"class":1304,"line":1359},[3792],{"type":41,"tag":1302,"props":3793,"children":3794},{},[3795],{"type":47,"value":3796}," * Text Domain: workflow-discovery-{name}\n",{"type":41,"tag":1302,"props":3798,"children":3799},{"class":1304,"line":1368},[3800],{"type":41,"tag":1302,"props":3801,"children":3802},{},[3803],{"type":47,"value":1374},{"type":41,"tag":1302,"props":3805,"children":3806},{"class":1304,"line":1377},[3807],{"type":41,"tag":1302,"props":3808,"children":3809},{},[3810],{"type":47,"value":3811}," * @package WorkflowDiscovery{PascalName}\n",{"type":41,"tag":1302,"props":3813,"children":3814},{"class":1304,"line":1386},[3815],{"type":41,"tag":1302,"props":3816,"children":3817},{},[3818],{"type":47,"value":1392},{"type":41,"tag":1302,"props":3820,"children":3821},{"class":1304,"line":1395},[3822],{"type":41,"tag":1302,"props":3823,"children":3824},{"emptyLinePlaceholder":1399},[3825],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3827,"children":3828},{"class":1304,"line":1405},[3829],{"type":41,"tag":1302,"props":3830,"children":3831},{},[3832],{"type":47,"value":1411},{"type":41,"tag":1302,"props":3834,"children":3835},{"class":1304,"line":1414},[3836],{"type":41,"tag":1302,"props":3837,"children":3838},{"emptyLinePlaceholder":1399},[3839],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3841,"children":3842},{"class":1304,"line":1422},[3843],{"type":41,"tag":1302,"props":3844,"children":3845},{},[3846],{"type":47,"value":3847},"namespace WorkflowDiscovery{PascalName};\n",{"type":41,"tag":1302,"props":3849,"children":3850},{"class":1304,"line":1431},[3851],{"type":41,"tag":1302,"props":3852,"children":3853},{"emptyLinePlaceholder":1399},[3854],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3856,"children":3857},{"class":1304,"line":1439},[3858],{"type":41,"tag":1302,"props":3859,"children":3860},{},[3861],{"type":47,"value":1445},{"type":41,"tag":1302,"props":3863,"children":3864},{"class":1304,"line":1448},[3865],{"type":41,"tag":1302,"props":3866,"children":3867},{},[3868],{"type":47,"value":1454},{"type":41,"tag":1302,"props":3870,"children":3871},{"class":1304,"line":1457},[3872],{"type":41,"tag":1302,"props":3873,"children":3874},{},[3875],{"type":47,"value":1463},{"type":41,"tag":1302,"props":3877,"children":3878},{"class":1304,"line":1466},[3879],{"type":41,"tag":1302,"props":3880,"children":3881},{"emptyLinePlaceholder":1399},[3882],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3884,"children":3885},{"class":1304,"line":1474},[3886],{"type":41,"tag":1302,"props":3887,"children":3888},{},[3889],{"type":47,"value":3890},"add_action( 'vip_workflows_register_discovery_providers', __NAMESPACE__ . '\\register' );\n",{"type":41,"tag":1302,"props":3892,"children":3893},{"class":1304,"line":1483},[3894],{"type":41,"tag":1302,"props":3895,"children":3896},{"emptyLinePlaceholder":1399},[3897],{"type":47,"value":1402},{"type":41,"tag":1302,"props":3899,"children":3900},{"class":1304,"line":1491},[3901],{"type":41,"tag":1302,"props":3902,"children":3903},{},[3904],{"type":47,"value":3905},"function register( $registry ): void {\n",{"type":41,"tag":1302,"props":3907,"children":3908},{"class":1304,"line":1500},[3909],{"type":41,"tag":1302,"props":3910,"children":3911},{},[3912],{"type":47,"value":3913},"    $registry->register( '{provider-slug}', array(\n",{"type":41,"tag":1302,"props":3915,"children":3916},{"class":1304,"line":1509},[3917],{"type":41,"tag":1302,"props":3918,"children":3919},{},[3920],{"type":47,"value":3921},"        'label'       => __( '{Display Name}', 'workflow-discovery-{name}' ),\n",{"type":41,"tag":1302,"props":3923,"children":3924},{"class":1304,"line":1518},[3925],{"type":41,"tag":1302,"props":3926,"children":3927},{},[3928],{"type":47,"value":3929},"        'description' => __( '{One-line description of what this provider surfaces.}', 'workflow-discovery-{name}' ),\n",{"type":41,"tag":1302,"props":3931,"children":3932},{"class":1304,"line":1527},[3933],{"type":41,"tag":1302,"props":3934,"children":3935},{},[3936],{"type":47,"value":3937},"        'icon'        => 'search',\n",{"type":41,"tag":1302,"props":3939,"children":3940},{"class":1304,"line":1535},[3941,3946],{"type":41,"tag":1302,"props":3942,"children":3943},{},[3944],{"type":47,"value":3945},"        'features'    => array( 'recommend', 'search' ),",{"type":41,"tag":1302,"props":3947,"children":3948},{},[3949],{"type":47,"value":3950}," \u002F\u002F keep only what you implement\n",{"type":41,"tag":1302,"props":3952,"children":3953},{"class":1304,"line":1544},[3954],{"type":41,"tag":1302,"props":3955,"children":3956},{},[3957],{"type":47,"value":3958},"        'callbacks'   => array(\n",{"type":41,"tag":1302,"props":3960,"children":3961},{"class":1304,"line":1553},[3962,3967],{"type":41,"tag":1302,"props":3963,"children":3964},{},[3965],{"type":47,"value":3966},"            'recommend' => __NAMESPACE__ . '\\get_recommendations',",{"type":41,"tag":1302,"props":3968,"children":3969},{},[3970],{"type":47,"value":3971}," \u002F\u002F required if 'recommend' in features\n",{"type":41,"tag":1302,"props":3973,"children":3974},{"class":1304,"line":1562},[3975,3980],{"type":41,"tag":1302,"props":3976,"children":3977},{},[3978],{"type":47,"value":3979},"            'search'    => __NAMESPACE__ . '\\search',",{"type":41,"tag":1302,"props":3981,"children":3982},{},[3983],{"type":47,"value":3984},"              \u002F\u002F required if 'search' in features\n",{"type":41,"tag":1302,"props":3986,"children":3987},{"class":1304,"line":1571},[3988,3993],{"type":41,"tag":1302,"props":3989,"children":3990},{},[3991],{"type":47,"value":3992},"            'filters'   => __NAMESPACE__ . '\\get_filters',",{"type":41,"tag":1302,"props":3994,"children":3995},{},[3996],{"type":47,"value":3997},"         \u002F\u002F required if 'search' in features\n",{"type":41,"tag":1302,"props":3999,"children":4000},{"class":1304,"line":1580},[4001,4006],{"type":41,"tag":1302,"props":4002,"children":4003},{},[4004],{"type":47,"value":4005},"            'seed'      => __NAMESPACE__ . '\\generate_seed',",{"type":41,"tag":1302,"props":4007,"children":4008},{},[4009],{"type":47,"value":4010},"       \u002F\u002F always required\n",{"type":41,"tag":1302,"props":4012,"children":4013},{"class":1304,"line":1589},[4014],{"type":41,"tag":1302,"props":4015,"children":4016},{},[4017],{"type":47,"value":4018},"        ),\n",{"type":41,"tag":1302,"props":4020,"children":4021},{"class":1304,"line":1598},[4022],{"type":41,"tag":1302,"props":4023,"children":4024},{},[4025],{"type":47,"value":4026},"        \u002F\u002F Uncomment if credentials are needed. See the Availability section below\n",{"type":41,"tag":1302,"props":4028,"children":4029},{"class":1304,"line":1607},[4030],{"type":41,"tag":1302,"props":4031,"children":4032},{},[4033],{"type":47,"value":4034},"        \u002F\u002F for the callback body.\n",{"type":41,"tag":1302,"props":4036,"children":4037},{"class":1304,"line":1616},[4038],{"type":41,"tag":1302,"props":4039,"children":4040},{},[4041],{"type":47,"value":4042},"        \u002F\u002F 'availability_callback' => __NAMESPACE__ . '\\check_availability',\n",{"type":41,"tag":1302,"props":4044,"children":4045},{"class":1304,"line":1625},[4046],{"type":41,"tag":1302,"props":4047,"children":4048},{},[4049],{"type":47,"value":4050},"    ) );\n",{"type":41,"tag":1302,"props":4052,"children":4053},{"class":1304,"line":26},[4054],{"type":41,"tag":1302,"props":4055,"children":4056},{},[4057],{"type":47,"value":1463},{"type":41,"tag":1302,"props":4059,"children":4060},{"class":1304,"line":1642},[4061],{"type":41,"tag":1302,"props":4062,"children":4063},{"emptyLinePlaceholder":1399},[4064],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4066,"children":4067},{"class":1304,"line":1651},[4068],{"type":41,"tag":1302,"props":4069,"children":4070},{},[4071],{"type":47,"value":1320},{"type":41,"tag":1302,"props":4073,"children":4074},{"class":1304,"line":1660},[4075],{"type":41,"tag":1302,"props":4076,"children":4077},{},[4078],{"type":47,"value":4079}," * Return curated prompts for the landing page.\n",{"type":41,"tag":1302,"props":4081,"children":4082},{"class":1304,"line":1669},[4083],{"type":41,"tag":1302,"props":4084,"children":4085},{},[4086],{"type":47,"value":1374},{"type":41,"tag":1302,"props":4088,"children":4089},{"class":1304,"line":1678},[4090],{"type":41,"tag":1302,"props":4091,"children":4092},{},[4093],{"type":47,"value":4094}," * Called on page load with the provider's saved settings.\n",{"type":41,"tag":1302,"props":4096,"children":4097},{"class":1304,"line":1687},[4098],{"type":41,"tag":1302,"props":4099,"children":4100},{},[4101],{"type":47,"value":4102}," * Return up to 6 prompts. Cache aggressively (see Caching section).\n",{"type":41,"tag":1302,"props":4104,"children":4105},{"class":1304,"line":1696},[4106],{"type":41,"tag":1302,"props":4107,"children":4108},{},[4109],{"type":47,"value":1374},{"type":41,"tag":1302,"props":4111,"children":4112},{"class":1304,"line":1704},[4113],{"type":41,"tag":1302,"props":4114,"children":4115},{},[4116],{"type":47,"value":4117}," * @param array $config Provider settings (categories, regions, etc.).\n",{"type":41,"tag":1302,"props":4119,"children":4120},{"class":1304,"line":1712},[4121],{"type":41,"tag":1302,"props":4122,"children":4123},{},[4124],{"type":47,"value":4125}," * @return array Array of story prompt arrays.\n",{"type":41,"tag":1302,"props":4127,"children":4128},{"class":1304,"line":1721},[4129],{"type":41,"tag":1302,"props":4130,"children":4131},{},[4132],{"type":47,"value":1392},{"type":41,"tag":1302,"props":4134,"children":4135},{"class":1304,"line":1730},[4136],{"type":41,"tag":1302,"props":4137,"children":4138},{},[4139],{"type":47,"value":4140},"function get_recommendations( array $config ): array {\n",{"type":41,"tag":1302,"props":4142,"children":4143},{"class":1304,"line":1738},[4144],{"type":41,"tag":1302,"props":4145,"children":4146},{},[4147],{"type":47,"value":4148},"    $response = wp_remote_get( 'https:\u002F\u002Fapi.example.com\u002Fupcoming', array( 'timeout' => 10 ) );\n",{"type":41,"tag":1302,"props":4150,"children":4151},{"class":1304,"line":1746},[4152],{"type":41,"tag":1302,"props":4153,"children":4154},{"emptyLinePlaceholder":1399},[4155],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4157,"children":4158},{"class":1304,"line":1755},[4159],{"type":41,"tag":1302,"props":4160,"children":4161},{},[4162],{"type":47,"value":2417},{"type":41,"tag":1302,"props":4164,"children":4165},{"class":1304,"line":1764},[4166],{"type":41,"tag":1302,"props":4167,"children":4168},{},[4169],{"type":47,"value":2426},{"type":41,"tag":1302,"props":4171,"children":4172},{"class":1304,"line":1773},[4173],{"type":41,"tag":1302,"props":4174,"children":4175},{},[4176],{"type":47,"value":1524},{"type":41,"tag":1302,"props":4178,"children":4179},{"class":1304,"line":1782},[4180],{"type":41,"tag":1302,"props":4181,"children":4182},{"emptyLinePlaceholder":1399},[4183],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4185,"children":4186},{"class":1304,"line":1791},[4187],{"type":41,"tag":1302,"props":4188,"children":4189},{},[4190],{"type":47,"value":2451},{"type":41,"tag":1302,"props":4192,"children":4193},{"class":1304,"line":1800},[4194],{"type":41,"tag":1302,"props":4195,"children":4196},{},[4197],{"type":47,"value":4198},"    $results = $body['items'] ?? array();\n",{"type":41,"tag":1302,"props":4200,"children":4201},{"class":1304,"line":1809},[4202],{"type":41,"tag":1302,"props":4203,"children":4204},{"emptyLinePlaceholder":1399},[4205],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4207,"children":4208},{"class":1304,"line":1818},[4209],{"type":41,"tag":1302,"props":4210,"children":4211},{},[4212],{"type":47,"value":4213},"    return array_map( __NAMESPACE__ . '\\normalize_prompt', array_slice( $results, 0, 6 ) );\n",{"type":41,"tag":1302,"props":4215,"children":4216},{"class":1304,"line":1827},[4217],{"type":41,"tag":1302,"props":4218,"children":4219},{},[4220],{"type":47,"value":1463},{"type":41,"tag":1302,"props":4222,"children":4223},{"class":1304,"line":1836},[4224],{"type":41,"tag":1302,"props":4225,"children":4226},{"emptyLinePlaceholder":1399},[4227],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4229,"children":4230},{"class":1304,"line":1845},[4231],{"type":41,"tag":1302,"props":4232,"children":4233},{},[4234],{"type":47,"value":1320},{"type":41,"tag":1302,"props":4236,"children":4237},{"class":1304,"line":1854},[4238],{"type":41,"tag":1302,"props":4239,"children":4240},{},[4241],{"type":47,"value":4242}," * Search for prompts matching user criteria.\n",{"type":41,"tag":1302,"props":4244,"children":4245},{"class":1304,"line":1863},[4246],{"type":41,"tag":1302,"props":4247,"children":4248},{},[4249],{"type":47,"value":1374},{"type":41,"tag":1302,"props":4251,"children":4252},{"class":1304,"line":1872},[4253],{"type":41,"tag":1302,"props":4254,"children":4255},{},[4256],{"type":47,"value":4257}," * @param array $params { text: string, filters: array\u003Cstring, mixed> }\n",{"type":41,"tag":1302,"props":4259,"children":4260},{"class":1304,"line":1881},[4261],{"type":41,"tag":1302,"props":4262,"children":4263},{},[4264],{"type":47,"value":4125},{"type":41,"tag":1302,"props":4266,"children":4267},{"class":1304,"line":1890},[4268],{"type":41,"tag":1302,"props":4269,"children":4270},{},[4271],{"type":47,"value":1392},{"type":41,"tag":1302,"props":4273,"children":4274},{"class":1304,"line":1899},[4275],{"type":41,"tag":1302,"props":4276,"children":4277},{},[4278],{"type":47,"value":4279},"function search( array $params ): array {\n",{"type":41,"tag":1302,"props":4281,"children":4282},{"class":1304,"line":1908},[4283],{"type":41,"tag":1302,"props":4284,"children":4285},{},[4286],{"type":47,"value":4287},"    $text    = $params['text'] ?? '';\n",{"type":41,"tag":1302,"props":4289,"children":4290},{"class":1304,"line":1917},[4291],{"type":41,"tag":1302,"props":4292,"children":4293},{},[4294],{"type":47,"value":4295},"    $filters = $params['filters'] ?? array();\n",{"type":41,"tag":1302,"props":4297,"children":4298},{"class":1304,"line":1926},[4299],{"type":41,"tag":1302,"props":4300,"children":4301},{"emptyLinePlaceholder":1399},[4302],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4304,"children":4305},{"class":1304,"line":1935},[4306],{"type":41,"tag":1302,"props":4307,"children":4308},{},[4309],{"type":47,"value":4310},"    $url      = add_query_arg( array( 'q' => $text ), 'https:\u002F\u002Fapi.example.com\u002Fsearch' );\n",{"type":41,"tag":1302,"props":4312,"children":4313},{"class":1304,"line":1944},[4314],{"type":41,"tag":1302,"props":4315,"children":4316},{},[4317],{"type":47,"value":2400},{"type":41,"tag":1302,"props":4319,"children":4320},{"class":1304,"line":1953},[4321],{"type":41,"tag":1302,"props":4322,"children":4323},{"emptyLinePlaceholder":1399},[4324],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4326,"children":4327},{"class":1304,"line":1962},[4328],{"type":41,"tag":1302,"props":4329,"children":4330},{},[4331],{"type":47,"value":2417},{"type":41,"tag":1302,"props":4333,"children":4334},{"class":1304,"line":1971},[4335],{"type":41,"tag":1302,"props":4336,"children":4337},{},[4338],{"type":47,"value":2426},{"type":41,"tag":1302,"props":4340,"children":4341},{"class":1304,"line":1979},[4342],{"type":41,"tag":1302,"props":4343,"children":4344},{},[4345],{"type":47,"value":1524},{"type":41,"tag":1302,"props":4347,"children":4348},{"class":1304,"line":1988},[4349],{"type":41,"tag":1302,"props":4350,"children":4351},{"emptyLinePlaceholder":1399},[4352],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4354,"children":4355},{"class":1304,"line":1997},[4356],{"type":41,"tag":1302,"props":4357,"children":4358},{},[4359],{"type":47,"value":2451},{"type":41,"tag":1302,"props":4361,"children":4362},{"class":1304,"line":2006},[4363],{"type":41,"tag":1302,"props":4364,"children":4365},{},[4366],{"type":47,"value":4198},{"type":41,"tag":1302,"props":4368,"children":4369},{"class":1304,"line":2014},[4370],{"type":41,"tag":1302,"props":4371,"children":4372},{"emptyLinePlaceholder":1399},[4373],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4375,"children":4376},{"class":1304,"line":2023},[4377],{"type":41,"tag":1302,"props":4378,"children":4379},{},[4380],{"type":47,"value":4381},"    return array_map( __NAMESPACE__ . '\\normalize_prompt', $results );\n",{"type":41,"tag":1302,"props":4383,"children":4384},{"class":1304,"line":2032},[4385],{"type":41,"tag":1302,"props":4386,"children":4387},{},[4388],{"type":47,"value":1463},{"type":41,"tag":1302,"props":4390,"children":4391},{"class":1304,"line":2040},[4392],{"type":41,"tag":1302,"props":4393,"children":4394},{"emptyLinePlaceholder":1399},[4395],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4397,"children":4398},{"class":1304,"line":2048},[4399],{"type":41,"tag":1302,"props":4400,"children":4401},{},[4402],{"type":47,"value":1320},{"type":41,"tag":1302,"props":4404,"children":4405},{"class":1304,"line":2056},[4406],{"type":41,"tag":1302,"props":4407,"children":4408},{},[4409],{"type":47,"value":4410}," * Return search filter definitions for the modal UI.\n",{"type":41,"tag":1302,"props":4412,"children":4413},{"class":1304,"line":2065},[4414],{"type":41,"tag":1302,"props":4415,"children":4416},{},[4417],{"type":47,"value":1374},{"type":41,"tag":1302,"props":4419,"children":4420},{"class":1304,"line":2073},[4421],{"type":41,"tag":1302,"props":4422,"children":4423},{},[4424],{"type":47,"value":4425}," * Supported types: 'select', 'multi_select', 'date_range'.\n",{"type":41,"tag":1302,"props":4427,"children":4428},{"class":1304,"line":2082},[4429],{"type":41,"tag":1302,"props":4430,"children":4431},{},[4432],{"type":47,"value":4433}," * Return an empty array if the provider has no filters but supports search.\n",{"type":41,"tag":1302,"props":4435,"children":4436},{"class":1304,"line":2091},[4437],{"type":41,"tag":1302,"props":4438,"children":4439},{},[4440],{"type":47,"value":1392},{"type":41,"tag":1302,"props":4442,"children":4443},{"class":1304,"line":2100},[4444],{"type":41,"tag":1302,"props":4445,"children":4446},{},[4447],{"type":47,"value":4448},"function get_filters(): array {\n",{"type":41,"tag":1302,"props":4450,"children":4451},{"class":1304,"line":2108},[4452],{"type":41,"tag":1302,"props":4453,"children":4454},{},[4455],{"type":47,"value":2331},{"type":41,"tag":1302,"props":4457,"children":4458},{"class":1304,"line":2117},[4459],{"type":41,"tag":1302,"props":4460,"children":4461},{},[4462],{"type":47,"value":1559},{"type":41,"tag":1302,"props":4464,"children":4465},{"class":1304,"line":2126},[4466],{"type":41,"tag":1302,"props":4467,"children":4468},{},[4469],{"type":47,"value":4470},"            'key'     => 'category',\n",{"type":41,"tag":1302,"props":4472,"children":4473},{"class":1304,"line":2134},[4474],{"type":41,"tag":1302,"props":4475,"children":4476},{},[4477],{"type":47,"value":4478},"            'label'   => __( 'Category', 'workflow-discovery-{name}' ),\n",{"type":41,"tag":1302,"props":4480,"children":4481},{"class":1304,"line":2143},[4482],{"type":41,"tag":1302,"props":4483,"children":4484},{},[4485],{"type":47,"value":4486},"            'type'    => 'select',\n",{"type":41,"tag":1302,"props":4488,"children":4489},{"class":1304,"line":2152},[4490],{"type":41,"tag":1302,"props":4491,"children":4492},{},[4493],{"type":47,"value":4494},"            'options' => array(\n",{"type":41,"tag":1302,"props":4496,"children":4497},{"class":1304,"line":2160},[4498],{"type":41,"tag":1302,"props":4499,"children":4500},{},[4501],{"type":47,"value":4502},"                array( 'value' => 'all', 'label' => 'All categories' ),\n",{"type":41,"tag":1302,"props":4504,"children":4505},{"class":1304,"line":2169},[4506],{"type":41,"tag":1302,"props":4507,"children":4508},{},[4509],{"type":47,"value":1684},{"type":41,"tag":1302,"props":4511,"children":4512},{"class":1304,"line":2178},[4513],{"type":41,"tag":1302,"props":4514,"children":4515},{},[4516],{"type":47,"value":4018},{"type":41,"tag":1302,"props":4518,"children":4519},{"class":1304,"line":2187},[4520],{"type":41,"tag":1302,"props":4521,"children":4522},{},[4523],{"type":47,"value":4524},"        \u002F\u002F array(\n",{"type":41,"tag":1302,"props":4526,"children":4527},{"class":1304,"line":2196},[4528],{"type":41,"tag":1302,"props":4529,"children":4530},{},[4531],{"type":47,"value":4532},"        \u002F\u002F     'key'     => 'date_range',\n",{"type":41,"tag":1302,"props":4534,"children":4535},{"class":1304,"line":2205},[4536],{"type":41,"tag":1302,"props":4537,"children":4538},{},[4539],{"type":47,"value":4540},"        \u002F\u002F     'label'   => __( 'Date range', 'workflow-discovery-{name}' ),\n",{"type":41,"tag":1302,"props":4542,"children":4543},{"class":1304,"line":2214},[4544],{"type":41,"tag":1302,"props":4545,"children":4546},{},[4547],{"type":47,"value":4548},"        \u002F\u002F     'type'    => 'date_range',\n",{"type":41,"tag":1302,"props":4550,"children":4551},{"class":1304,"line":2223},[4552],{"type":41,"tag":1302,"props":4553,"children":4554},{},[4555],{"type":47,"value":4556},"        \u002F\u002F     'default' => array( 'from' => 'today', 'to' => '+90 days' ),\n",{"type":41,"tag":1302,"props":4558,"children":4559},{"class":1304,"line":2231},[4560],{"type":41,"tag":1302,"props":4561,"children":4562},{},[4563],{"type":47,"value":4564},"        \u002F\u002F ),\n",{"type":41,"tag":1302,"props":4566,"children":4567},{"class":1304,"line":2239},[4568],{"type":41,"tag":1302,"props":4569,"children":4570},{},[4571],{"type":47,"value":2029},{"type":41,"tag":1302,"props":4573,"children":4574},{"class":1304,"line":2248},[4575],{"type":41,"tag":1302,"props":4576,"children":4577},{},[4578],{"type":47,"value":1463},{"type":41,"tag":1302,"props":4580,"children":4581},{"class":1304,"line":2257},[4582],{"type":41,"tag":1302,"props":4583,"children":4584},{"emptyLinePlaceholder":1399},[4585],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4587,"children":4588},{"class":1304,"line":2266},[4589],{"type":41,"tag":1302,"props":4590,"children":4591},{},[4592],{"type":47,"value":1320},{"type":41,"tag":1302,"props":4594,"children":4595},{"class":1304,"line":2274},[4596],{"type":41,"tag":1302,"props":4597,"children":4598},{},[4599],{"type":47,"value":4600}," * Compose a seed string from a selected prompt.\n",{"type":41,"tag":1302,"props":4602,"children":4603},{"class":1304,"line":2282},[4604],{"type":41,"tag":1302,"props":4605,"children":4606},{},[4607],{"type":47,"value":1374},{"type":41,"tag":1302,"props":4609,"children":4610},{"class":1304,"line":2291},[4611],{"type":41,"tag":1302,"props":4612,"children":4613},{},[4614],{"type":47,"value":4615}," * Called when an editor clicks a prompt card. The returned string becomes\n",{"type":41,"tag":1302,"props":4617,"children":4618},{"class":1304,"line":2300},[4619],{"type":41,"tag":1302,"props":4620,"children":4621},{},[4622],{"type":47,"value":4623}," * the seed for a new ideation project. Include the most relevant context\n",{"type":41,"tag":1302,"props":4625,"children":4626},{"class":1304,"line":2309},[4627],{"type":41,"tag":1302,"props":4628,"children":4629},{},[4630],{"type":47,"value":4631}," * your data source provides.\n",{"type":41,"tag":1302,"props":4633,"children":4634},{"class":1304,"line":2317},[4635],{"type":41,"tag":1302,"props":4636,"children":4637},{},[4638],{"type":47,"value":1392},{"type":41,"tag":1302,"props":4640,"children":4641},{"class":1304,"line":2325},[4642],{"type":41,"tag":1302,"props":4643,"children":4644},{},[4645],{"type":47,"value":4646},"function generate_seed( array $prompt ): string {\n",{"type":41,"tag":1302,"props":4648,"children":4649},{"class":1304,"line":2334},[4650],{"type":41,"tag":1302,"props":4651,"children":4652},{},[4653],{"type":47,"value":4654},"    $parts = array( $prompt['title'] );\n",{"type":41,"tag":1302,"props":4656,"children":4657},{"class":1304,"line":2343},[4658],{"type":41,"tag":1302,"props":4659,"children":4660},{"emptyLinePlaceholder":1399},[4661],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4663,"children":4664},{"class":1304,"line":2352},[4665],{"type":41,"tag":1302,"props":4666,"children":4667},{},[4668],{"type":47,"value":4669},"    if ( ! empty( $prompt['description'] ) ) {\n",{"type":41,"tag":1302,"props":4671,"children":4672},{"class":1304,"line":2360},[4673],{"type":41,"tag":1302,"props":4674,"children":4675},{},[4676],{"type":47,"value":4677},"        $parts[] = $prompt['description'];\n",{"type":41,"tag":1302,"props":4679,"children":4680},{"class":1304,"line":2368},[4681],{"type":41,"tag":1302,"props":4682,"children":4683},{},[4684],{"type":47,"value":1524},{"type":41,"tag":1302,"props":4686,"children":4687},{"class":1304,"line":2376},[4688],{"type":41,"tag":1302,"props":4689,"children":4690},{},[4691],{"type":47,"value":4692},"    if ( ! empty( $prompt['date'] ) ) {\n",{"type":41,"tag":1302,"props":4694,"children":4695},{"class":1304,"line":2385},[4696],{"type":41,"tag":1302,"props":4697,"children":4698},{},[4699],{"type":47,"value":4700},"        $parts[] = sprintf( 'Scheduled for %s.', date( 'F j, Y', strtotime( $prompt['date'] ) ) );\n",{"type":41,"tag":1302,"props":4702,"children":4703},{"class":1304,"line":2394},[4704],{"type":41,"tag":1302,"props":4705,"children":4706},{},[4707],{"type":47,"value":1524},{"type":41,"tag":1302,"props":4709,"children":4710},{"class":1304,"line":2403},[4711],{"type":41,"tag":1302,"props":4712,"children":4713},{},[4714],{"type":47,"value":4715},"    if ( ! empty( $prompt['tags'] ) ) {\n",{"type":41,"tag":1302,"props":4717,"children":4718},{"class":1304,"line":2411},[4719],{"type":41,"tag":1302,"props":4720,"children":4721},{},[4722],{"type":47,"value":4723},"        $parts[] = sprintf( 'Topics: %s.', implode( ', ', $prompt['tags'] ) );\n",{"type":41,"tag":1302,"props":4725,"children":4726},{"class":1304,"line":2420},[4727],{"type":41,"tag":1302,"props":4728,"children":4729},{},[4730],{"type":47,"value":1524},{"type":41,"tag":1302,"props":4732,"children":4733},{"class":1304,"line":2429},[4734],{"type":41,"tag":1302,"props":4735,"children":4736},{"emptyLinePlaceholder":1399},[4737],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4739,"children":4740},{"class":1304,"line":2437},[4741],{"type":41,"tag":1302,"props":4742,"children":4743},{},[4744],{"type":47,"value":4745},"    return implode( ' ', $parts );\n",{"type":41,"tag":1302,"props":4747,"children":4748},{"class":1304,"line":2445},[4749],{"type":41,"tag":1302,"props":4750,"children":4751},{},[4752],{"type":47,"value":1463},{"type":41,"tag":1302,"props":4754,"children":4755},{"class":1304,"line":2454},[4756],{"type":41,"tag":1302,"props":4757,"children":4758},{"emptyLinePlaceholder":1399},[4759],{"type":47,"value":1402},{"type":41,"tag":1302,"props":4761,"children":4762},{"class":1304,"line":2463},[4763],{"type":41,"tag":1302,"props":4764,"children":4765},{},[4766],{"type":47,"value":4767},"function normalize_prompt( array $item ): array {\n",{"type":41,"tag":1302,"props":4769,"children":4770},{"class":1304,"line":2472},[4771],{"type":41,"tag":1302,"props":4772,"children":4773},{},[4774],{"type":47,"value":2331},{"type":41,"tag":1302,"props":4776,"children":4777},{"class":1304,"line":2480},[4778],{"type":41,"tag":1302,"props":4779,"children":4780},{},[4781],{"type":47,"value":4782},"        'id'          => '{provider-slug}-' . ( $item['id'] ?? '' ),\n",{"type":41,"tag":1302,"props":4784,"children":4785},{"class":1304,"line":2489},[4786],{"type":41,"tag":1302,"props":4787,"children":4788},{},[4789],{"type":47,"value":4790},"        'provider'    => '{provider-slug}',\n",{"type":41,"tag":1302,"props":4792,"children":4793},{"class":1304,"line":2498},[4794],{"type":41,"tag":1302,"props":4795,"children":4796},{},[4797],{"type":47,"value":4798},"        'title'       => $item['title'] ?? '',\n",{"type":41,"tag":1302,"props":4800,"children":4801},{"class":1304,"line":2507},[4802],{"type":41,"tag":1302,"props":4803,"children":4804},{},[4805],{"type":47,"value":4806},"        'description' => $item['description'] ?? '',\n",{"type":41,"tag":1302,"props":4808,"children":4809},{"class":1304,"line":2516},[4810],{"type":41,"tag":1302,"props":4811,"children":4812},{},[4813],{"type":47,"value":4814},"        'url'         => $item['url'] ?? '',\n",{"type":41,"tag":1302,"props":4816,"children":4817},{"class":1304,"line":2525},[4818],{"type":41,"tag":1302,"props":4819,"children":4820},{},[4821],{"type":47,"value":4822},"        'date'        => $item['date'] ?? null,\n",{"type":41,"tag":1302,"props":4824,"children":4825},{"class":1304,"line":2534},[4826],{"type":41,"tag":1302,"props":4827,"children":4828},{},[4829],{"type":47,"value":4830},"        'date_end'    => $item['date_end'] ?? null,\n",{"type":41,"tag":1302,"props":4832,"children":4833},{"class":1304,"line":2543},[4834],{"type":41,"tag":1302,"props":4835,"children":4836},{},[4837],{"type":47,"value":4838},"        'tags'        => $item['tags'] ?? array(),\n",{"type":41,"tag":1302,"props":4840,"children":4841},{"class":1304,"line":2552},[4842],{"type":41,"tag":1302,"props":4843,"children":4844},{},[4845],{"type":47,"value":4846},"        'importance'  => $item['importance'] ?? 'normal',\n",{"type":41,"tag":1302,"props":4848,"children":4849},{"class":1304,"line":2561},[4850],{"type":41,"tag":1302,"props":4851,"children":4852},{},[4853],{"type":47,"value":4854},"        'meta'        => $item['meta'] ?? array(),\n",{"type":41,"tag":1302,"props":4856,"children":4857},{"class":1304,"line":2570},[4858],{"type":41,"tag":1302,"props":4859,"children":4860},{},[4861],{"type":47,"value":2029},{"type":41,"tag":1302,"props":4863,"children":4864},{"class":1304,"line":2579},[4865],{"type":41,"tag":1302,"props":4866,"children":4867},{},[4868],{"type":47,"value":1463},{"type":41,"tag":2646,"props":4870,"children":4872},{"id":4871},"story-prompt-shape",[4873],{"type":47,"value":4874},"Story Prompt Shape",{"type":41,"tag":50,"props":4876,"children":4877},{},[4878,4880,4884],{"type":47,"value":4879},"Every prompt ",{"type":41,"tag":56,"props":4881,"children":4882},{},[4883],{"type":47,"value":2661},{"type":47,"value":2663},{"type":41,"tag":71,"props":4886,"children":4887},{},[4888,4906,4917],{"type":41,"tag":75,"props":4889,"children":4890},{},[4891,4897,4899,4905],{"type":41,"tag":125,"props":4892,"children":4894},{"className":4893},[],[4895],{"type":47,"value":4896},"id",{"type":47,"value":4898}," — provider-namespaced unique identifier (e.g., ",{"type":41,"tag":125,"props":4900,"children":4902},{"className":4901},[],[4903],{"type":47,"value":4904},"foresight-703721",{"type":47,"value":296},{"type":41,"tag":75,"props":4907,"children":4908},{},[4909,4915],{"type":41,"tag":125,"props":4910,"children":4912},{"className":4911},[],[4913],{"type":47,"value":4914},"provider",{"type":47,"value":4916}," — the provider slug",{"type":41,"tag":75,"props":4918,"children":4919},{},[4920,4925],{"type":41,"tag":125,"props":4921,"children":4923},{"className":4922},[],[4924],{"type":47,"value":2731},{"type":47,"value":2733},{"type":41,"tag":50,"props":4927,"children":4928},{},[4929,4930,4936,4937,4942,4943,4948,4949,4955,4956,4962,4963,4969,4970,4976],{"type":47,"value":2749},{"type":41,"tag":125,"props":4931,"children":4933},{"className":4932},[],[4934],{"type":47,"value":4935},"description",{"type":47,"value":909},{"type":41,"tag":125,"props":4938,"children":4940},{"className":4939},[],[4941],{"type":47,"value":2742},{"type":47,"value":909},{"type":41,"tag":125,"props":4944,"children":4946},{"className":4945},[],[4947],{"type":47,"value":2783},{"type":47,"value":909},{"type":41,"tag":125,"props":4950,"children":4952},{"className":4951},[],[4953],{"type":47,"value":4954},"date_end",{"type":47,"value":909},{"type":41,"tag":125,"props":4957,"children":4959},{"className":4958},[],[4960],{"type":47,"value":4961},"tags",{"type":47,"value":909},{"type":41,"tag":125,"props":4964,"children":4966},{"className":4965},[],[4967],{"type":47,"value":4968},"importance",{"type":47,"value":909},{"type":41,"tag":125,"props":4971,"children":4973},{"className":4972},[],[4974],{"type":47,"value":4975},"meta",{"type":47,"value":971},{"type":41,"tag":50,"props":4978,"children":4979},{},[4980,4985,4987,4993,4994,5000,5001,5007,5009,5014],{"type":41,"tag":125,"props":4981,"children":4983},{"className":4982},[],[4984],{"type":47,"value":4968},{"type":47,"value":4986}," is provider-defined. The UI renders badges based on it (",{"type":41,"tag":125,"props":4988,"children":4990},{"className":4989},[],[4991],{"type":47,"value":4992},"key_event",{"type":47,"value":909},{"type":41,"tag":125,"props":4995,"children":4997},{"className":4996},[],[4998],{"type":47,"value":4999},"top_story",{"type":47,"value":909},{"type":41,"tag":125,"props":5002,"children":5004},{"className":5003},[],[5005],{"type":47,"value":5006},"normal",{"type":47,"value":5008},") but does not enforce a universal scale. ",{"type":41,"tag":125,"props":5010,"children":5012},{"className":5011},[],[5013],{"type":47,"value":4975},{"type":47,"value":5015}," is freeform and provider-specific — use it for structured data your seed generation or settings UI needs (event types, regions, contacts, embargo info, etc.).",{"type":41,"tag":134,"props":5017,"children":5019},{"id":5018},"boilerplate-research-discovery",[5020],{"type":47,"value":5021},"Boilerplate: Research + Discovery",{"type":41,"tag":50,"props":5023,"children":5024},{},[5025,5027,5032],{"type":47,"value":5026},"Use this when one plugin provides both capabilities (e.g., Qwoted surfaces journalist requests as prompts ",{"type":41,"tag":86,"props":5028,"children":5029},{},[5030],{"type":47,"value":5031},"and",{"type":47,"value":5033}," finds expert sources during research).",{"type":41,"tag":50,"props":5035,"children":5036},{},[5037],{"type":47,"value":5038},"Register both independently, then declare a unified agent manifest so the Agents tab renders a single card covering both with a shared label, icon, description, and settings form.",{"type":41,"tag":1175,"props":5040,"children":5042},{"className":1294,"code":5041,"language":1296,"meta":1183,"style":1183},"\u003C?php\n\u002F**\n * Plugin Name: Workflow {Display Name}\n * Description: {Short description combining both capabilities.}\n * Version: 1.0.0\n * Requires Plugins: vip-workflows\n * Text Domain: workflow-{name}\n *\n * @package Workflow{PascalName}\n *\u002F\n\ndeclare( strict_types=1 );\n\nnamespace Workflow{PascalName};\n\nif ( ! defined( 'ABSPATH' ) ) {\n    exit;\n}\n\n\u002F\u002F Register the research ability.\nadd_action( 'wp_abilities_api_init', __NAMESPACE__ . '\\register_ability' );\n\nfunction register_ability(): void {\n    if ( ! function_exists( 'vip_workflows_register_ability' ) ) {\n        return;\n    }\n\n    vip_workflows_register_ability(\n        'workflow-{name}\u002F{ability-slug}',\n        array(\n            'label'               => __( '{Display Name}', 'workflow-{name}' ),\n            'description'         => __( '{Research description.}', 'workflow-{name}' ),\n            'category'            => 'research',\n            \u002F\u002F ... input_schema, output_schema, execute_callback, permission_callback\n            'meta'                => array(\n                'type'         => 'research',\n                'show_in_rest' => true,\n                'icon'         => 'search',\n            ),\n        )\n    );\n}\n\n\u002F\u002F Register the discovery provider.\nadd_action( 'vip_workflows_register_discovery_providers', __NAMESPACE__ . '\\register_provider' );\n\nfunction register_provider( $registry ): void {\n    $registry->register( '{provider-slug}', array(\n        'label'     => __( '{Display Name}', 'workflow-{name}' ),\n        'icon'      => 'search',\n        'features'  => array( 'recommend', 'search' ),\n        'callbacks' => array(\n            'recommend' => __NAMESPACE__ . '\\get_recommendations',\n            'search'    => __NAMESPACE__ . '\\search_prompts',\n            'filters'   => __NAMESPACE__ . '\\get_filters',\n            'seed'      => __NAMESPACE__ . '\\generate_seed',\n        ),\n    ) );\n}\n\n\u002F\u002F Declare the unified manifest so both appear as a single card.\nadd_action( 'vip_workflows_register_assistant_meta', __NAMESPACE__ . '\\register_assistant_meta' );\n\nfunction register_assistant_meta( $registry ): void {\n    $registry->register( 'workflow-{name}', array(\n        'label'           => __( '{Display Name}', 'workflow-{name}' ),\n        'description'     => __( 'Expert sources and story prompts from {source}.', 'workflow-{name}' ),\n        'icon'            => 'search',\n        'ability_ids'     => array( 'workflow-{name}\u002F{ability-slug}' ),\n        'provider_slugs'  => array( '{provider-slug}' ),\n        'settings_schema' => array(\n            'api_key' => array(\n                'type'     => 'string',\n                'label'    => 'API Key',\n                'required' => true,\n                'secret'   => true,\n            ),\n        ),\n    ) );\n}\n",[5043],{"type":41,"tag":125,"props":5044,"children":5045},{"__ignoreMap":1183},[5046,5053,5060,5068,5076,5083,5090,5098,5105,5113,5120,5127,5134,5141,5149,5156,5163,5170,5177,5184,5192,5200,5207,5215,5222,5229,5236,5243,5250,5258,5265,5273,5281,5288,5296,5303,5311,5319,5327,5334,5341,5348,5355,5362,5370,5378,5385,5393,5400,5408,5416,5424,5432,5440,5448,5456,5464,5471,5478,5485,5492,5500,5508,5515,5523,5531,5539,5547,5555,5563,5571,5579,5587,5595,5603,5611,5619,5626,5633,5640],{"type":41,"tag":1302,"props":5047,"children":5048},{"class":1304,"line":1305},[5049],{"type":41,"tag":1302,"props":5050,"children":5051},{},[5052],{"type":47,"value":1311},{"type":41,"tag":1302,"props":5054,"children":5055},{"class":1304,"line":1314},[5056],{"type":41,"tag":1302,"props":5057,"children":5058},{},[5059],{"type":47,"value":1320},{"type":41,"tag":1302,"props":5061,"children":5062},{"class":1304,"line":1323},[5063],{"type":41,"tag":1302,"props":5064,"children":5065},{},[5066],{"type":47,"value":5067}," * Plugin Name: Workflow {Display Name}\n",{"type":41,"tag":1302,"props":5069,"children":5070},{"class":1304,"line":1332},[5071],{"type":41,"tag":1302,"props":5072,"children":5073},{},[5074],{"type":47,"value":5075}," * Description: {Short description combining both capabilities.}\n",{"type":41,"tag":1302,"props":5077,"children":5078},{"class":1304,"line":1341},[5079],{"type":41,"tag":1302,"props":5080,"children":5081},{},[5082],{"type":47,"value":1347},{"type":41,"tag":1302,"props":5084,"children":5085},{"class":1304,"line":1350},[5086],{"type":41,"tag":1302,"props":5087,"children":5088},{},[5089],{"type":47,"value":1356},{"type":41,"tag":1302,"props":5091,"children":5092},{"class":1304,"line":1359},[5093],{"type":41,"tag":1302,"props":5094,"children":5095},{},[5096],{"type":47,"value":5097}," * Text Domain: workflow-{name}\n",{"type":41,"tag":1302,"props":5099,"children":5100},{"class":1304,"line":1368},[5101],{"type":41,"tag":1302,"props":5102,"children":5103},{},[5104],{"type":47,"value":1374},{"type":41,"tag":1302,"props":5106,"children":5107},{"class":1304,"line":1377},[5108],{"type":41,"tag":1302,"props":5109,"children":5110},{},[5111],{"type":47,"value":5112}," * @package Workflow{PascalName}\n",{"type":41,"tag":1302,"props":5114,"children":5115},{"class":1304,"line":1386},[5116],{"type":41,"tag":1302,"props":5117,"children":5118},{},[5119],{"type":47,"value":1392},{"type":41,"tag":1302,"props":5121,"children":5122},{"class":1304,"line":1395},[5123],{"type":41,"tag":1302,"props":5124,"children":5125},{"emptyLinePlaceholder":1399},[5126],{"type":47,"value":1402},{"type":41,"tag":1302,"props":5128,"children":5129},{"class":1304,"line":1405},[5130],{"type":41,"tag":1302,"props":5131,"children":5132},{},[5133],{"type":47,"value":1411},{"type":41,"tag":1302,"props":5135,"children":5136},{"class":1304,"line":1414},[5137],{"type":41,"tag":1302,"props":5138,"children":5139},{"emptyLinePlaceholder":1399},[5140],{"type":47,"value":1402},{"type":41,"tag":1302,"props":5142,"children":5143},{"class":1304,"line":1422},[5144],{"type":41,"tag":1302,"props":5145,"children":5146},{},[5147],{"type":47,"value":5148},"namespace Workflow{PascalName};\n",{"type":41,"tag":1302,"props":5150,"children":5151},{"class":1304,"line":1431},[5152],{"type":41,"tag":1302,"props":5153,"children":5154},{"emptyLinePlaceholder":1399},[5155],{"type":47,"value":1402},{"type":41,"tag":1302,"props":5157,"children":5158},{"class":1304,"line":1439},[5159],{"type":41,"tag":1302,"props":5160,"children":5161},{},[5162],{"type":47,"value":1445},{"type":41,"tag":1302,"props":5164,"children":5165},{"class":1304,"line":1448},[5166],{"type":41,"tag":1302,"props":5167,"children":5168},{},[5169],{"type":47,"value":1454},{"type":41,"tag":1302,"props":5171,"children":5172},{"class":1304,"line":1457},[5173],{"type":41,"tag":1302,"props":5174,"children":5175},{},[5176],{"type":47,"value":1463},{"type":41,"tag":1302,"props":5178,"children":5179},{"class":1304,"line":1466},[5180],{"type":41,"tag":1302,"props":5181,"children":5182},{"emptyLinePlaceholder":1399},[5183],{"type":47,"value":1402},{"type":41,"tag":1302,"props":5185,"children":5186},{"class":1304,"line":1474},[5187],{"type":41,"tag":1302,"props":5188,"children":5189},{},[5190],{"type":47,"value":5191},"\u002F\u002F Register the research ability.\n",{"type":41,"tag":1302,"props":5193,"children":5194},{"class":1304,"line":1483},[5195],{"type":41,"tag":1302,"props":5196,"children":5197},{},[5198],{"type":47,"value":5199},"add_action( 'wp_abilities_api_init', __NAMESPACE__ . '\\register_ability' );\n",{"type":41,"tag":1302,"props":5201,"children":5202},{"class":1304,"line":1491},[5203],{"type":41,"tag":1302,"props":5204,"children":5205},{"emptyLinePlaceholder":1399},[5206],{"type":47,"value":1402},{"type":41,"tag":1302,"props":5208,"children":5209},{"class":1304,"line":1500},[5210],{"type":41,"tag":1302,"props":5211,"children":5212},{},[5213],{"type":47,"value":5214},"function register_ability(): void {\n",{"type":41,"tag":1302,"props":5216,"children":5217},{"class":1304,"line":1509},[5218],{"type":41,"tag":1302,"props":5219,"children":5220},{},[5221],{"type":47,"value":1506},{"type":41,"tag":1302,"props":5223,"children":5224},{"class":1304,"line":1518},[5225],{"type":41,"tag":1302,"props":5226,"children":5227},{},[5228],{"type":47,"value":1515},{"type":41,"tag":1302,"props":5230,"children":5231},{"class":1304,"line":1527},[5232],{"type":41,"tag":1302,"props":5233,"children":5234},{},[5235],{"type":47,"value":1524},{"type":41,"tag":1302,"props":5237,"children":5238},{"class":1304,"line":1535},[5239],{"type":41,"tag":1302,"props":5240,"children":5241},{"emptyLinePlaceholder":1399},[5242],{"type":47,"value":1402},{"type":41,"tag":1302,"props":5244,"children":5245},{"class":1304,"line":1544},[5246],{"type":41,"tag":1302,"props":5247,"children":5248},{},[5249],{"type":47,"value":1541},{"type":41,"tag":1302,"props":5251,"children":5252},{"class":1304,"line":1553},[5253],{"type":41,"tag":1302,"props":5254,"children":5255},{},[5256],{"type":47,"value":5257},"        'workflow-{name}\u002F{ability-slug}',\n",{"type":41,"tag":1302,"props":5259,"children":5260},{"class":1304,"line":1562},[5261],{"type":41,"tag":1302,"props":5262,"children":5263},{},[5264],{"type":47,"value":1559},{"type":41,"tag":1302,"props":5266,"children":5267},{"class":1304,"line":1571},[5268],{"type":41,"tag":1302,"props":5269,"children":5270},{},[5271],{"type":47,"value":5272},"            'label'               => __( '{Display Name}', 'workflow-{name}' ),\n",{"type":41,"tag":1302,"props":5274,"children":5275},{"class":1304,"line":1580},[5276],{"type":41,"tag":1302,"props":5277,"children":5278},{},[5279],{"type":47,"value":5280},"            'description'         => __( '{Research description.}', 'workflow-{name}' ),\n",{"type":41,"tag":1302,"props":5282,"children":5283},{"class":1304,"line":1589},[5284],{"type":41,"tag":1302,"props":5285,"children":5286},{},[5287],{"type":47,"value":1586},{"type":41,"tag":1302,"props":5289,"children":5290},{"class":1304,"line":1598},[5291],{"type":41,"tag":1302,"props":5292,"children":5293},{},[5294],{"type":47,"value":5295},"            \u002F\u002F ... input_schema, output_schema, execute_callback, permission_callback\n",{"type":41,"tag":1302,"props":5297,"children":5298},{"class":1304,"line":1607},[5299],{"type":41,"tag":1302,"props":5300,"children":5301},{},[5302],{"type":47,"value":1788},{"type":41,"tag":1302,"props":5304,"children":5305},{"class":1304,"line":1616},[5306],{"type":41,"tag":1302,"props":5307,"children":5308},{},[5309],{"type":47,"value":5310},"                'type'         => 'research',\n",{"type":41,"tag":1302,"props":5312,"children":5313},{"class":1304,"line":1625},[5314],{"type":41,"tag":1302,"props":5315,"children":5316},{},[5317],{"type":47,"value":5318},"                'show_in_rest' => true,\n",{"type":41,"tag":1302,"props":5320,"children":5321},{"class":1304,"line":26},[5322],{"type":41,"tag":1302,"props":5323,"children":5324},{},[5325],{"type":47,"value":5326},"                'icon'         => 'search',\n",{"type":41,"tag":1302,"props":5328,"children":5329},{"class":1304,"line":1642},[5330],{"type":41,"tag":1302,"props":5331,"children":5332},{},[5333],{"type":47,"value":1684},{"type":41,"tag":1302,"props":5335,"children":5336},{"class":1304,"line":1651},[5337],{"type":41,"tag":1302,"props":5338,"children":5339},{},[5340],{"type":47,"value":2020},{"type":41,"tag":1302,"props":5342,"children":5343},{"class":1304,"line":1660},[5344],{"type":41,"tag":1302,"props":5345,"children":5346},{},[5347],{"type":47,"value":2029},{"type":41,"tag":1302,"props":5349,"children":5350},{"class":1304,"line":1669},[5351],{"type":41,"tag":1302,"props":5352,"children":5353},{},[5354],{"type":47,"value":1463},{"type":41,"tag":1302,"props":5356,"children":5357},{"class":1304,"line":1678},[5358],{"type":41,"tag":1302,"props":5359,"children":5360},{"emptyLinePlaceholder":1399},[5361],{"type":47,"value":1402},{"type":41,"tag":1302,"props":5363,"children":5364},{"class":1304,"line":1687},[5365],{"type":41,"tag":1302,"props":5366,"children":5367},{},[5368],{"type":47,"value":5369},"\u002F\u002F Register the discovery provider.\n",{"type":41,"tag":1302,"props":5371,"children":5372},{"class":1304,"line":1696},[5373],{"type":41,"tag":1302,"props":5374,"children":5375},{},[5376],{"type":47,"value":5377},"add_action( 'vip_workflows_register_discovery_providers', __NAMESPACE__ . '\\register_provider' );\n",{"type":41,"tag":1302,"props":5379,"children":5380},{"class":1304,"line":1704},[5381],{"type":41,"tag":1302,"props":5382,"children":5383},{"emptyLinePlaceholder":1399},[5384],{"type":47,"value":1402},{"type":41,"tag":1302,"props":5386,"children":5387},{"class":1304,"line":1712},[5388],{"type":41,"tag":1302,"props":5389,"children":5390},{},[5391],{"type":47,"value":5392},"function register_provider( $registry ): void {\n",{"type":41,"tag":1302,"props":5394,"children":5395},{"class":1304,"line":1721},[5396],{"type":41,"tag":1302,"props":5397,"children":5398},{},[5399],{"type":47,"value":3913},{"type":41,"tag":1302,"props":5401,"children":5402},{"class":1304,"line":1730},[5403],{"type":41,"tag":1302,"props":5404,"children":5405},{},[5406],{"type":47,"value":5407},"        'label'     => __( '{Display Name}', 'workflow-{name}' ),\n",{"type":41,"tag":1302,"props":5409,"children":5410},{"class":1304,"line":1738},[5411],{"type":41,"tag":1302,"props":5412,"children":5413},{},[5414],{"type":47,"value":5415},"        'icon'      => 'search',\n",{"type":41,"tag":1302,"props":5417,"children":5418},{"class":1304,"line":1746},[5419],{"type":41,"tag":1302,"props":5420,"children":5421},{},[5422],{"type":47,"value":5423},"        'features'  => array( 'recommend', 'search' ),\n",{"type":41,"tag":1302,"props":5425,"children":5426},{"class":1304,"line":1755},[5427],{"type":41,"tag":1302,"props":5428,"children":5429},{},[5430],{"type":47,"value":5431},"        'callbacks' => array(\n",{"type":41,"tag":1302,"props":5433,"children":5434},{"class":1304,"line":1764},[5435],{"type":41,"tag":1302,"props":5436,"children":5437},{},[5438],{"type":47,"value":5439},"            'recommend' => __NAMESPACE__ . '\\get_recommendations',\n",{"type":41,"tag":1302,"props":5441,"children":5442},{"class":1304,"line":1773},[5443],{"type":41,"tag":1302,"props":5444,"children":5445},{},[5446],{"type":47,"value":5447},"            'search'    => __NAMESPACE__ . '\\search_prompts',\n",{"type":41,"tag":1302,"props":5449,"children":5450},{"class":1304,"line":1782},[5451],{"type":41,"tag":1302,"props":5452,"children":5453},{},[5454],{"type":47,"value":5455},"            'filters'   => __NAMESPACE__ . '\\get_filters',\n",{"type":41,"tag":1302,"props":5457,"children":5458},{"class":1304,"line":1791},[5459],{"type":41,"tag":1302,"props":5460,"children":5461},{},[5462],{"type":47,"value":5463},"            'seed'      => __NAMESPACE__ . '\\generate_seed',\n",{"type":41,"tag":1302,"props":5465,"children":5466},{"class":1304,"line":1800},[5467],{"type":41,"tag":1302,"props":5468,"children":5469},{},[5470],{"type":47,"value":4018},{"type":41,"tag":1302,"props":5472,"children":5473},{"class":1304,"line":1809},[5474],{"type":41,"tag":1302,"props":5475,"children":5476},{},[5477],{"type":47,"value":4050},{"type":41,"tag":1302,"props":5479,"children":5480},{"class":1304,"line":1818},[5481],{"type":41,"tag":1302,"props":5482,"children":5483},{},[5484],{"type":47,"value":1463},{"type":41,"tag":1302,"props":5486,"children":5487},{"class":1304,"line":1827},[5488],{"type":41,"tag":1302,"props":5489,"children":5490},{"emptyLinePlaceholder":1399},[5491],{"type":47,"value":1402},{"type":41,"tag":1302,"props":5493,"children":5494},{"class":1304,"line":1836},[5495],{"type":41,"tag":1302,"props":5496,"children":5497},{},[5498],{"type":47,"value":5499},"\u002F\u002F Declare the unified manifest so both appear as a single card.\n",{"type":41,"tag":1302,"props":5501,"children":5502},{"class":1304,"line":1845},[5503],{"type":41,"tag":1302,"props":5504,"children":5505},{},[5506],{"type":47,"value":5507},"add_action( 'vip_workflows_register_assistant_meta', __NAMESPACE__ . '\\register_assistant_meta' );\n",{"type":41,"tag":1302,"props":5509,"children":5510},{"class":1304,"line":1854},[5511],{"type":41,"tag":1302,"props":5512,"children":5513},{"emptyLinePlaceholder":1399},[5514],{"type":47,"value":1402},{"type":41,"tag":1302,"props":5516,"children":5517},{"class":1304,"line":1863},[5518],{"type":41,"tag":1302,"props":5519,"children":5520},{},[5521],{"type":47,"value":5522},"function register_assistant_meta( $registry ): void {\n",{"type":41,"tag":1302,"props":5524,"children":5525},{"class":1304,"line":1872},[5526],{"type":41,"tag":1302,"props":5527,"children":5528},{},[5529],{"type":47,"value":5530},"    $registry->register( 'workflow-{name}', array(\n",{"type":41,"tag":1302,"props":5532,"children":5533},{"class":1304,"line":1881},[5534],{"type":41,"tag":1302,"props":5535,"children":5536},{},[5537],{"type":47,"value":5538},"        'label'           => __( '{Display Name}', 'workflow-{name}' ),\n",{"type":41,"tag":1302,"props":5540,"children":5541},{"class":1304,"line":1890},[5542],{"type":41,"tag":1302,"props":5543,"children":5544},{},[5545],{"type":47,"value":5546},"        'description'     => __( 'Expert sources and story prompts from {source}.', 'workflow-{name}' ),\n",{"type":41,"tag":1302,"props":5548,"children":5549},{"class":1304,"line":1899},[5550],{"type":41,"tag":1302,"props":5551,"children":5552},{},[5553],{"type":47,"value":5554},"        'icon'            => 'search',\n",{"type":41,"tag":1302,"props":5556,"children":5557},{"class":1304,"line":1908},[5558],{"type":41,"tag":1302,"props":5559,"children":5560},{},[5561],{"type":47,"value":5562},"        'ability_ids'     => array( 'workflow-{name}\u002F{ability-slug}' ),\n",{"type":41,"tag":1302,"props":5564,"children":5565},{"class":1304,"line":1917},[5566],{"type":41,"tag":1302,"props":5567,"children":5568},{},[5569],{"type":47,"value":5570},"        'provider_slugs'  => array( '{provider-slug}' ),\n",{"type":41,"tag":1302,"props":5572,"children":5573},{"class":1304,"line":1926},[5574],{"type":41,"tag":1302,"props":5575,"children":5576},{},[5577],{"type":47,"value":5578},"        'settings_schema' => array(\n",{"type":41,"tag":1302,"props":5580,"children":5581},{"class":1304,"line":1935},[5582],{"type":41,"tag":1302,"props":5583,"children":5584},{},[5585],{"type":47,"value":5586},"            'api_key' => array(\n",{"type":41,"tag":1302,"props":5588,"children":5589},{"class":1304,"line":1944},[5590],{"type":41,"tag":1302,"props":5591,"children":5592},{},[5593],{"type":47,"value":5594},"                'type'     => 'string',\n",{"type":41,"tag":1302,"props":5596,"children":5597},{"class":1304,"line":1953},[5598],{"type":41,"tag":1302,"props":5599,"children":5600},{},[5601],{"type":47,"value":5602},"                'label'    => 'API Key',\n",{"type":41,"tag":1302,"props":5604,"children":5605},{"class":1304,"line":1962},[5606],{"type":41,"tag":1302,"props":5607,"children":5608},{},[5609],{"type":47,"value":5610},"                'required' => true,\n",{"type":41,"tag":1302,"props":5612,"children":5613},{"class":1304,"line":1971},[5614],{"type":41,"tag":1302,"props":5615,"children":5616},{},[5617],{"type":47,"value":5618},"                'secret'   => true,\n",{"type":41,"tag":1302,"props":5620,"children":5621},{"class":1304,"line":1979},[5622],{"type":41,"tag":1302,"props":5623,"children":5624},{},[5625],{"type":47,"value":1684},{"type":41,"tag":1302,"props":5627,"children":5628},{"class":1304,"line":1988},[5629],{"type":41,"tag":1302,"props":5630,"children":5631},{},[5632],{"type":47,"value":4018},{"type":41,"tag":1302,"props":5634,"children":5635},{"class":1304,"line":1997},[5636],{"type":41,"tag":1302,"props":5637,"children":5638},{},[5639],{"type":47,"value":4050},{"type":41,"tag":1302,"props":5641,"children":5642},{"class":1304,"line":2006},[5643],{"type":41,"tag":1302,"props":5644,"children":5645},{},[5646],{"type":47,"value":1463},{"type":41,"tag":50,"props":5648,"children":5649},{},[5650],{"type":47,"value":5651},"Without a manifest, the two registrations would show up as two separate cards. The manifest is only needed when one plugin spans both capabilities. Single-capability plugins are auto-detected and need no manifest.",{"type":41,"tag":134,"props":5653,"children":5655},{"id":5654},"availability",[5656],{"type":47,"value":1167},{"type":41,"tag":50,"props":5658,"children":5659},{},[5660,5662,5667,5669,5674,5676,5682],{"type":47,"value":5661},"An agent that needs configuration declares an ",{"type":41,"tag":125,"props":5663,"children":5665},{"className":5664},[],[5666],{"type":47,"value":1112},{"type":47,"value":5668}," — in ",{"type":41,"tag":125,"props":5670,"children":5672},{"className":5671},[],[5673],{"type":47,"value":4975},{"type":47,"value":5675}," for an ability, as a top-level key for a discovery provider. Write it against the structured shape from the start: returning a bare ",{"type":41,"tag":125,"props":5677,"children":5679},{"className":5678},[],[5680],{"type":47,"value":5681},"false",{"type":47,"value":5683}," gets the card a generic \"required settings are not configured\" line that names nothing and links nowhere.",{"type":41,"tag":50,"props":5685,"children":5686},{},[5687],{"type":41,"tag":56,"props":5688,"children":5689},{},[5690],{"type":47,"value":5691},"Return either:",{"type":41,"tag":146,"props":5693,"children":5694},{},[5695,5711],{"type":41,"tag":150,"props":5696,"children":5697},{},[5698],{"type":41,"tag":154,"props":5699,"children":5700},{},[5701,5706],{"type":41,"tag":158,"props":5702,"children":5703},{},[5704],{"type":47,"value":5705},"Return value",{"type":41,"tag":158,"props":5707,"children":5708},{},[5709],{"type":47,"value":5710},"Meaning",{"type":41,"tag":184,"props":5712,"children":5713},{},[5714,5739,5756],{"type":41,"tag":154,"props":5715,"children":5716},{},[5717,5726],{"type":41,"tag":191,"props":5718,"children":5719},{},[5720],{"type":41,"tag":125,"props":5721,"children":5723},{"className":5722},[],[5724],{"type":47,"value":5725},"true",{"type":41,"tag":191,"props":5727,"children":5728},{},[5729,5731,5737],{"type":47,"value":5730},"Dependencies are met. Return this the moment they are — including when only one member of an ",{"type":41,"tag":125,"props":5732,"children":5734},{"className":5733},[],[5735],{"type":47,"value":5736},"any",{"type":47,"value":5738}," group is satisfied.",{"type":41,"tag":154,"props":5740,"children":5741},{},[5742,5751],{"type":41,"tag":191,"props":5743,"children":5744},{},[5745],{"type":41,"tag":125,"props":5746,"children":5748},{"className":5747},[],[5749],{"type":47,"value":5750},"VIPWorkflows\\Abilities\\Availability::unmet( ... )",{"type":41,"tag":191,"props":5752,"children":5753},{},[5754],{"type":47,"value":5755},"Dependencies are not met, carrying the unmet requirements.",{"type":41,"tag":154,"props":5757,"children":5758},{},[5759,5767],{"type":41,"tag":191,"props":5760,"children":5761},{},[5762],{"type":41,"tag":125,"props":5763,"children":5765},{"className":5764},[],[5766],{"type":47,"value":5681},{"type":41,"tag":191,"props":5768,"children":5769},{},[5770],{"type":47,"value":5771},"Legacy shape. Still supported and silent, but the card can only render the generic line.",{"type":41,"tag":50,"props":5773,"children":5774},{},[5775,5780,5782,5787,5789,5795],{"type":41,"tag":56,"props":5776,"children":5777},{},[5778],{"type":47,"value":5779},"The callback owns satisfaction.",{"type":47,"value":5781}," It is the only code with credential access, so nothing downstream re-derives it: a requirement group contains ",{"type":41,"tag":86,"props":5783,"children":5784},{},[5785],{"type":47,"value":5786},"only",{"type":47,"value":5788}," unmet members, and ",{"type":41,"tag":125,"props":5790,"children":5792},{"className":5791},[],[5793],{"type":47,"value":5794},"Availability::unmet()",{"type":47,"value":5796}," is never returned for a dependency that is actually satisfied.",{"type":41,"tag":50,"props":5798,"children":5799},{},[5800,5811,5813,5819,5821,5827,5829,5835],{"type":41,"tag":56,"props":5801,"children":5802},{},[5803,5805],{"type":47,"value":5804},"Build requirements with ",{"type":41,"tag":125,"props":5806,"children":5808},{"className":5807},[],[5809],{"type":47,"value":5810},"RequirementFactory",{"type":47,"value":5812},", not by hand. Hand-construction means supplying an id, a kind, two message registers, source attribution, and a destination; the factory derives all of it, and resolves the destination against the install rather than hardcoding a screen that may not exist. Construct a ",{"type":41,"tag":125,"props":5814,"children":5816},{"className":5815},[],[5817],{"type":47,"value":5818},"Requirement",{"type":47,"value":5820}," directly only when no factory fits — for example a key read from your own ",{"type":41,"tag":125,"props":5822,"children":5824},{"className":5823},[],[5825],{"type":47,"value":5826},"wp-config.php",{"type":47,"value":5828}," constant, which needs ",{"type":41,"tag":125,"props":5830,"children":5832},{"className":5831},[],[5833],{"type":47,"value":5834},"Destination::none()",{"type":47,"value":5836}," naming that constant.",{"type":41,"tag":146,"props":5838,"children":5839},{},[5840,5856],{"type":41,"tag":150,"props":5841,"children":5842},{},[5843],{"type":41,"tag":154,"props":5844,"children":5845},{},[5846,5851],{"type":41,"tag":158,"props":5847,"children":5848},{},[5849],{"type":47,"value":5850},"Factory method",{"type":41,"tag":158,"props":5852,"children":5853},{},[5854],{"type":47,"value":5855},"Use when",{"type":41,"tag":184,"props":5857,"children":5858},{},[5859,5883,5914,5931],{"type":41,"tag":154,"props":5860,"children":5861},{},[5862,5871],{"type":41,"tag":191,"props":5863,"children":5864},{},[5865],{"type":41,"tag":125,"props":5866,"children":5868},{"className":5867},[],[5869],{"type":47,"value":5870},"in_card( $id, $admin_reason, $user_message, $hint, $sources )",{"type":41,"tag":191,"props":5872,"children":5873},{},[5874,5876,5881],{"type":47,"value":5875},"The key is entered in the agent's own card fields (",{"type":41,"tag":125,"props":5877,"children":5879},{"className":5878},[],[5880],{"type":47,"value":961},{"type":47,"value":5882},"). This is the usual case for a third-party agent.",{"type":41,"tag":154,"props":5884,"children":5885},{},[5886,5895],{"type":41,"tag":191,"props":5887,"children":5888},{},[5889],{"type":41,"tag":125,"props":5890,"children":5892},{"className":5891},[],[5893],{"type":47,"value":5894},"missing_credential( $service, $service_label, $sources )",{"type":41,"tag":191,"props":5896,"children":5897},{},[5898,5900,5905,5907,5912],{"type":47,"value":5899},"The key is one the plugin reads through ",{"type":41,"tag":125,"props":5901,"children":5903},{"className":5902},[],[5904],{"type":47,"value":1135},{"type":47,"value":5906},". Derives everything from the service slug, and resolves to Settings → Connectors or to the ",{"type":41,"tag":125,"props":5908,"children":5910},{"className":5909},[],[5911],{"type":47,"value":5826},{"type":47,"value":5913}," constant name depending on the install.",{"type":41,"tag":154,"props":5915,"children":5916},{},[5917,5926],{"type":41,"tag":191,"props":5918,"children":5919},{},[5920],{"type":41,"tag":125,"props":5921,"children":5923},{"className":5922},[],[5924],{"type":47,"value":5925},"dependency( $id, $admin_reason, $user_message, $sources )",{"type":41,"tag":191,"props":5927,"children":5928},{},[5929],{"type":47,"value":5930},"A prerequisite other than a credential is missing (e.g. no provider is registered).",{"type":41,"tag":154,"props":5932,"children":5933},{},[5934,5943],{"type":41,"tag":191,"props":5935,"children":5936},{},[5937],{"type":41,"tag":125,"props":5938,"children":5940},{"className":5939},[],[5941],{"type":47,"value":5942},"unsupported_environment( $id, $admin_reason, $user_message, $sources )",{"type":41,"tag":191,"props":5944,"children":5945},{},[5946],{"type":47,"value":5947},"The environment cannot support the capability, so there is nothing to configure.",{"type":41,"tag":50,"props":5949,"children":5950},{},[5951,5953,5959,5961,5967,5969,5974],{"type":47,"value":5952},"Group members with ",{"type":41,"tag":125,"props":5954,"children":5956},{"className":5955},[],[5957],{"type":47,"value":5958},"RequirementGroup::all()",{"type":47,"value":5960}," when every one is needed, or ",{"type":41,"tag":125,"props":5962,"children":5964},{"className":5963},[],[5965],{"type":47,"value":5966},"RequirementGroup::any()",{"type":47,"value":5968}," when one is enough — an ",{"type":41,"tag":125,"props":5970,"children":5972},{"className":5971},[],[5973],{"type":47,"value":5736},{"type":47,"value":5975}," group renders as a single \"configure at least one of\" block rather than N separate blockers.",{"type":41,"tag":1175,"props":5977,"children":5979},{"className":1294,"code":5978,"language":1296,"meta":1183,"style":1183},"use VIPWorkflows\\Abilities\\Availability;\nuse VIPWorkflows\\Abilities\\RequirementFactory;\nuse VIPWorkflows\\Abilities\\RequirementGroup;\n\n\u002F**\n * Whether this agent's dependencies are met, and what is missing if not.\n *\n * Registered as the `availability_callback` for both the ability and the\n * discovery provider. Sharing one callback means both contribute the same\n * requirement id, so the card renders one row listing both capabilities.\n *\u002F\nfunction check_availability(): bool|Availability {\n    if ( is_configured() ) {\n        return true;\n    }\n\n    return Availability::unmet(\n        RequirementGroup::all(\n            RequirementFactory::in_card(\n                'settings:workflow-{name}',\n                __( '{Display Name} sign-in details are missing. Add the API key below.', 'workflow-{name}' ),\n                __( '{Display Name} is not connected. Ask an administrator to connect it.', 'workflow-{name}' ),\n                __( 'Complete the API key field below.', 'workflow-{name}' ),\n                array( __( '{Display Name}', 'workflow-{name}' ) )\n            )\n        )\n    );\n}\n\nfunction is_configured(): bool {\n    $settings = \\VIPWorkflows\\Abilities\\AbilitySettings::get_instance();\n    $options  = $settings->get_options( 'workflow-agent-{name}\u002F{slug}' );\n\n    return ! empty( $options['api_key'] );\n}\n",[5980],{"type":41,"tag":125,"props":5981,"children":5982},{"__ignoreMap":1183},[5983,5991,5999,6007,6014,6021,6029,6036,6044,6052,6060,6067,6075,6083,6091,6098,6105,6113,6121,6129,6137,6145,6153,6161,6169,6177,6184,6191,6198,6205,6213,6221,6229,6236,6244],{"type":41,"tag":1302,"props":5984,"children":5985},{"class":1304,"line":1305},[5986],{"type":41,"tag":1302,"props":5987,"children":5988},{},[5989],{"type":47,"value":5990},"use VIPWorkflows\\Abilities\\Availability;\n",{"type":41,"tag":1302,"props":5992,"children":5993},{"class":1304,"line":1314},[5994],{"type":41,"tag":1302,"props":5995,"children":5996},{},[5997],{"type":47,"value":5998},"use VIPWorkflows\\Abilities\\RequirementFactory;\n",{"type":41,"tag":1302,"props":6000,"children":6001},{"class":1304,"line":1323},[6002],{"type":41,"tag":1302,"props":6003,"children":6004},{},[6005],{"type":47,"value":6006},"use VIPWorkflows\\Abilities\\RequirementGroup;\n",{"type":41,"tag":1302,"props":6008,"children":6009},{"class":1304,"line":1332},[6010],{"type":41,"tag":1302,"props":6011,"children":6012},{"emptyLinePlaceholder":1399},[6013],{"type":47,"value":1402},{"type":41,"tag":1302,"props":6015,"children":6016},{"class":1304,"line":1341},[6017],{"type":41,"tag":1302,"props":6018,"children":6019},{},[6020],{"type":47,"value":1320},{"type":41,"tag":1302,"props":6022,"children":6023},{"class":1304,"line":1350},[6024],{"type":41,"tag":1302,"props":6025,"children":6026},{},[6027],{"type":47,"value":6028}," * Whether this agent's dependencies are met, and what is missing if not.\n",{"type":41,"tag":1302,"props":6030,"children":6031},{"class":1304,"line":1359},[6032],{"type":41,"tag":1302,"props":6033,"children":6034},{},[6035],{"type":47,"value":1374},{"type":41,"tag":1302,"props":6037,"children":6038},{"class":1304,"line":1368},[6039],{"type":41,"tag":1302,"props":6040,"children":6041},{},[6042],{"type":47,"value":6043}," * Registered as the `availability_callback` for both the ability and the\n",{"type":41,"tag":1302,"props":6045,"children":6046},{"class":1304,"line":1377},[6047],{"type":41,"tag":1302,"props":6048,"children":6049},{},[6050],{"type":47,"value":6051}," * discovery provider. Sharing one callback means both contribute the same\n",{"type":41,"tag":1302,"props":6053,"children":6054},{"class":1304,"line":1386},[6055],{"type":41,"tag":1302,"props":6056,"children":6057},{},[6058],{"type":47,"value":6059}," * requirement id, so the card renders one row listing both capabilities.\n",{"type":41,"tag":1302,"props":6061,"children":6062},{"class":1304,"line":1395},[6063],{"type":41,"tag":1302,"props":6064,"children":6065},{},[6066],{"type":47,"value":1392},{"type":41,"tag":1302,"props":6068,"children":6069},{"class":1304,"line":1405},[6070],{"type":41,"tag":1302,"props":6071,"children":6072},{},[6073],{"type":47,"value":6074},"function check_availability(): bool|Availability {\n",{"type":41,"tag":1302,"props":6076,"children":6077},{"class":1304,"line":1414},[6078],{"type":41,"tag":1302,"props":6079,"children":6080},{},[6081],{"type":47,"value":6082},"    if ( is_configured() ) {\n",{"type":41,"tag":1302,"props":6084,"children":6085},{"class":1304,"line":1422},[6086],{"type":41,"tag":1302,"props":6087,"children":6088},{},[6089],{"type":47,"value":6090},"        return true;\n",{"type":41,"tag":1302,"props":6092,"children":6093},{"class":1304,"line":1431},[6094],{"type":41,"tag":1302,"props":6095,"children":6096},{},[6097],{"type":47,"value":1524},{"type":41,"tag":1302,"props":6099,"children":6100},{"class":1304,"line":1439},[6101],{"type":41,"tag":1302,"props":6102,"children":6103},{"emptyLinePlaceholder":1399},[6104],{"type":47,"value":1402},{"type":41,"tag":1302,"props":6106,"children":6107},{"class":1304,"line":1448},[6108],{"type":41,"tag":1302,"props":6109,"children":6110},{},[6111],{"type":47,"value":6112},"    return Availability::unmet(\n",{"type":41,"tag":1302,"props":6114,"children":6115},{"class":1304,"line":1457},[6116],{"type":41,"tag":1302,"props":6117,"children":6118},{},[6119],{"type":47,"value":6120},"        RequirementGroup::all(\n",{"type":41,"tag":1302,"props":6122,"children":6123},{"class":1304,"line":1466},[6124],{"type":41,"tag":1302,"props":6125,"children":6126},{},[6127],{"type":47,"value":6128},"            RequirementFactory::in_card(\n",{"type":41,"tag":1302,"props":6130,"children":6131},{"class":1304,"line":1474},[6132],{"type":41,"tag":1302,"props":6133,"children":6134},{},[6135],{"type":47,"value":6136},"                'settings:workflow-{name}',\n",{"type":41,"tag":1302,"props":6138,"children":6139},{"class":1304,"line":1483},[6140],{"type":41,"tag":1302,"props":6141,"children":6142},{},[6143],{"type":47,"value":6144},"                __( '{Display Name} sign-in details are missing. Add the API key below.', 'workflow-{name}' ),\n",{"type":41,"tag":1302,"props":6146,"children":6147},{"class":1304,"line":1491},[6148],{"type":41,"tag":1302,"props":6149,"children":6150},{},[6151],{"type":47,"value":6152},"                __( '{Display Name} is not connected. Ask an administrator to connect it.', 'workflow-{name}' ),\n",{"type":41,"tag":1302,"props":6154,"children":6155},{"class":1304,"line":1500},[6156],{"type":41,"tag":1302,"props":6157,"children":6158},{},[6159],{"type":47,"value":6160},"                __( 'Complete the API key field below.', 'workflow-{name}' ),\n",{"type":41,"tag":1302,"props":6162,"children":6163},{"class":1304,"line":1509},[6164],{"type":41,"tag":1302,"props":6165,"children":6166},{},[6167],{"type":47,"value":6168},"                array( __( '{Display Name}', 'workflow-{name}' ) )\n",{"type":41,"tag":1302,"props":6170,"children":6171},{"class":1304,"line":1518},[6172],{"type":41,"tag":1302,"props":6173,"children":6174},{},[6175],{"type":47,"value":6176},"            )\n",{"type":41,"tag":1302,"props":6178,"children":6179},{"class":1304,"line":1527},[6180],{"type":41,"tag":1302,"props":6181,"children":6182},{},[6183],{"type":47,"value":2020},{"type":41,"tag":1302,"props":6185,"children":6186},{"class":1304,"line":1535},[6187],{"type":41,"tag":1302,"props":6188,"children":6189},{},[6190],{"type":47,"value":2029},{"type":41,"tag":1302,"props":6192,"children":6193},{"class":1304,"line":1544},[6194],{"type":41,"tag":1302,"props":6195,"children":6196},{},[6197],{"type":47,"value":1463},{"type":41,"tag":1302,"props":6199,"children":6200},{"class":1304,"line":1553},[6201],{"type":41,"tag":1302,"props":6202,"children":6203},{"emptyLinePlaceholder":1399},[6204],{"type":47,"value":1402},{"type":41,"tag":1302,"props":6206,"children":6207},{"class":1304,"line":1562},[6208],{"type":41,"tag":1302,"props":6209,"children":6210},{},[6211],{"type":47,"value":6212},"function is_configured(): bool {\n",{"type":41,"tag":1302,"props":6214,"children":6215},{"class":1304,"line":1571},[6216],{"type":41,"tag":1302,"props":6217,"children":6218},{},[6219],{"type":47,"value":6220},"    $settings = \\VIPWorkflows\\Abilities\\AbilitySettings::get_instance();\n",{"type":41,"tag":1302,"props":6222,"children":6223},{"class":1304,"line":1580},[6224],{"type":41,"tag":1302,"props":6225,"children":6226},{},[6227],{"type":47,"value":6228},"    $options  = $settings->get_options( 'workflow-agent-{name}\u002F{slug}' );\n",{"type":41,"tag":1302,"props":6230,"children":6231},{"class":1304,"line":1589},[6232],{"type":41,"tag":1302,"props":6233,"children":6234},{"emptyLinePlaceholder":1399},[6235],{"type":47,"value":1402},{"type":41,"tag":1302,"props":6237,"children":6238},{"class":1304,"line":1598},[6239],{"type":41,"tag":1302,"props":6240,"children":6241},{},[6242],{"type":47,"value":6243},"    return ! empty( $options['api_key'] );\n",{"type":41,"tag":1302,"props":6245,"children":6246},{"class":1304,"line":1607},[6247],{"type":41,"tag":1302,"props":6248,"children":6249},{},[6250],{"type":47,"value":1463},{"type":41,"tag":50,"props":6252,"children":6253},{},[6254,6259,6261,6267,6269,6275,6277,6283,6285,6291],{"type":41,"tag":56,"props":6255,"children":6256},{},[6257],{"type":47,"value":6258},"Two message registers, and you must supply both.",{"type":47,"value":6260}," Agent execution is gated on ",{"type":41,"tag":125,"props":6262,"children":6264},{"className":6263},[],[6265],{"type":47,"value":6266},"edit_posts",{"type":47,"value":6268},", while the Agents screen and Settings → Connectors both require ",{"type":41,"tag":125,"props":6270,"children":6272},{"className":6271},[],[6273],{"type":47,"value":6274},"manage_options",{"type":47,"value":6276},". The ",{"type":41,"tag":125,"props":6278,"children":6280},{"className":6279},[],[6281],{"type":47,"value":6282},"$admin_reason",{"type":47,"value":6284}," may name a screen; the ",{"type":41,"tag":125,"props":6286,"children":6288},{"className":6287},[],[6289],{"type":47,"value":6290},"$user_message",{"type":47,"value":6292}," must not — it is what an editor sees mid-workflow, and pointing them at a page they cannot open is a dead instruction. Which register is emitted is decided at the read boundary, not by you.",{"type":41,"tag":50,"props":6294,"children":6295},{},[6296,6298,6303,6305,6310,6312,6317,6319,6324],{"type":47,"value":6297},"Note the separation the Agents card preserves: ",{"type":41,"tag":56,"props":6299,"children":6300},{},[6301],{"type":47,"value":6302},"enabled",{"type":47,"value":6304}," is an admin preference, ",{"type":41,"tag":56,"props":6306,"children":6307},{},[6308],{"type":47,"value":6309},"available",{"type":47,"value":6311}," is whether dependencies are satisfied. Returning ",{"type":41,"tag":125,"props":6313,"children":6315},{"className":6314},[],[6316],{"type":47,"value":5681},{"type":47,"value":6318}," from ",{"type":41,"tag":125,"props":6320,"children":6322},{"className":6321},[],[6323],{"type":47,"value":1112},{"type":47,"value":6325}," does not disable an agent, and an admin disabling an agent does not make it unavailable.",{"type":41,"tag":134,"props":6327,"children":6329},{"id":6328},"settings-ui-optional",[6330],{"type":47,"value":6331},"Settings UI (Optional)",{"type":41,"tag":50,"props":6333,"children":6334},{},[6335],{"type":47,"value":6336},"If the agent needs configuration, there are two paths:",{"type":41,"tag":50,"props":6338,"children":6339},{},[6340,6345,6347,6352,6354,6359,6361,6367],{"type":41,"tag":56,"props":6341,"children":6342},{},[6343],{"type":47,"value":6344},"Schema-based (recommended).",{"type":47,"value":6346}," Declare ",{"type":41,"tag":125,"props":6348,"children":6350},{"className":6349},[],[6351],{"type":47,"value":961},{"type":47,"value":6353}," — in the ability ",{"type":41,"tag":125,"props":6355,"children":6357},{"className":6356},[],[6358],{"type":47,"value":4975},{"type":47,"value":6360}," for research-only, in the provider config for discovery-only, or in the unified manifest for both. The Agents tab auto-renders the form via ",{"type":41,"tag":125,"props":6362,"children":6364},{"className":6363},[],[6365],{"type":47,"value":6366},"SchemaSettings",{"type":47,"value":6368},". No JS needed.",{"type":41,"tag":50,"props":6370,"children":6371},{},[6372,6377],{"type":41,"tag":56,"props":6373,"children":6374},{},[6375],{"type":47,"value":6376},"Fully custom React UI.",{"type":47,"value":6378}," Inject a component via the unified JS filter:",{"type":41,"tag":1175,"props":6380,"children":6384},{"className":6381,"code":6382,"language":6383,"meta":1183,"style":1183},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { addFilter } from '@wordpress\u002Fhooks';\n\naddFilter(\n    'vipWorkflows.assistantSettings',\n    'workflow-{name}',\n    ( component, assistant, { disabled, onHasChangesChange, onSaveRef } ) => {\n        \u002F\u002F Match on your ability id, not on `assistant.slug`. An entry slug is\n        \u002F\u002F derived, and only a manifest controls its own: an agent with no\n        \u002F\u002F manifest gets a slug built from its whole ability id\n        \u002F\u002F (`workflow-{name}-{slug}`), so a slug comparison silently stops\n        \u002F\u002F matching. Ability ids are yours and never change under you.\n        if ( ! assistant.ability_ids?.includes( 'workflow-{name}\u002F{slug}' ) ) {\n            return component;\n        }\n\n        return (\n            \u003CSettingsForm\n                assistant={ assistant }\n                disabled={ disabled }\n                onHasChangesChange={ onHasChangesChange }\n                onSaveRef={ onSaveRef }\n            \u002F>\n        );\n    }\n);\n","javascript",[6385],{"type":41,"tag":125,"props":6386,"children":6387},{"__ignoreMap":1183},[6388,6440,6447,6461,6483,6502,6577,6586,6594,6602,6610,6618,6688,6704,6711,6718,6731,6745,6767,6788,6809,6830,6838,6850,6857],{"type":41,"tag":1302,"props":6389,"children":6390},{"class":1304,"line":1305},[6391,6397,6403,6409,6414,6419,6424,6430,6435],{"type":41,"tag":1302,"props":6392,"children":6394},{"style":6393},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[6395],{"type":47,"value":6396},"import",{"type":41,"tag":1302,"props":6398,"children":6400},{"style":6399},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[6401],{"type":47,"value":6402}," {",{"type":41,"tag":1302,"props":6404,"children":6406},{"style":6405},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[6407],{"type":47,"value":6408}," addFilter",{"type":41,"tag":1302,"props":6410,"children":6411},{"style":6399},[6412],{"type":47,"value":6413}," }",{"type":41,"tag":1302,"props":6415,"children":6416},{"style":6393},[6417],{"type":47,"value":6418}," from",{"type":41,"tag":1302,"props":6420,"children":6421},{"style":6399},[6422],{"type":47,"value":6423}," '",{"type":41,"tag":1302,"props":6425,"children":6427},{"style":6426},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[6428],{"type":47,"value":6429},"@wordpress\u002Fhooks",{"type":41,"tag":1302,"props":6431,"children":6432},{"style":6399},[6433],{"type":47,"value":6434},"'",{"type":41,"tag":1302,"props":6436,"children":6437},{"style":6399},[6438],{"type":47,"value":6439},";\n",{"type":41,"tag":1302,"props":6441,"children":6442},{"class":1304,"line":1314},[6443],{"type":41,"tag":1302,"props":6444,"children":6445},{"emptyLinePlaceholder":1399},[6446],{"type":47,"value":1402},{"type":41,"tag":1302,"props":6448,"children":6449},{"class":1304,"line":1323},[6450,6456],{"type":41,"tag":1302,"props":6451,"children":6453},{"style":6452},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[6454],{"type":47,"value":6455},"addFilter",{"type":41,"tag":1302,"props":6457,"children":6458},{"style":6405},[6459],{"type":47,"value":6460},"(\n",{"type":41,"tag":1302,"props":6462,"children":6463},{"class":1304,"line":1332},[6464,6469,6474,6478],{"type":41,"tag":1302,"props":6465,"children":6466},{"style":6399},[6467],{"type":47,"value":6468},"    '",{"type":41,"tag":1302,"props":6470,"children":6471},{"style":6426},[6472],{"type":47,"value":6473},"vipWorkflows.assistantSettings",{"type":41,"tag":1302,"props":6475,"children":6476},{"style":6399},[6477],{"type":47,"value":6434},{"type":41,"tag":1302,"props":6479,"children":6480},{"style":6399},[6481],{"type":47,"value":6482},",\n",{"type":41,"tag":1302,"props":6484,"children":6485},{"class":1304,"line":1341},[6486,6490,6494,6498],{"type":41,"tag":1302,"props":6487,"children":6488},{"style":6399},[6489],{"type":47,"value":6468},{"type":41,"tag":1302,"props":6491,"children":6492},{"style":6426},[6493],{"type":47,"value":1273},{"type":41,"tag":1302,"props":6495,"children":6496},{"style":6399},[6497],{"type":47,"value":6434},{"type":41,"tag":1302,"props":6499,"children":6500},{"style":6399},[6501],{"type":47,"value":6482},{"type":41,"tag":1302,"props":6503,"children":6504},{"class":1304,"line":1350},[6505,6510,6516,6521,6526,6530,6534,6539,6543,6548,6552,6557,6561,6566,6572],{"type":41,"tag":1302,"props":6506,"children":6507},{"style":6399},[6508],{"type":47,"value":6509},"    (",{"type":41,"tag":1302,"props":6511,"children":6513},{"style":6512},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic",[6514],{"type":47,"value":6515}," component",{"type":41,"tag":1302,"props":6517,"children":6518},{"style":6399},[6519],{"type":47,"value":6520},",",{"type":41,"tag":1302,"props":6522,"children":6523},{"style":6512},[6524],{"type":47,"value":6525}," assistant",{"type":41,"tag":1302,"props":6527,"children":6528},{"style":6399},[6529],{"type":47,"value":6520},{"type":41,"tag":1302,"props":6531,"children":6532},{"style":6399},[6533],{"type":47,"value":6402},{"type":41,"tag":1302,"props":6535,"children":6536},{"style":6512},[6537],{"type":47,"value":6538}," disabled",{"type":41,"tag":1302,"props":6540,"children":6541},{"style":6399},[6542],{"type":47,"value":6520},{"type":41,"tag":1302,"props":6544,"children":6545},{"style":6512},[6546],{"type":47,"value":6547}," onHasChangesChange",{"type":41,"tag":1302,"props":6549,"children":6550},{"style":6399},[6551],{"type":47,"value":6520},{"type":41,"tag":1302,"props":6553,"children":6554},{"style":6512},[6555],{"type":47,"value":6556}," onSaveRef",{"type":41,"tag":1302,"props":6558,"children":6559},{"style":6399},[6560],{"type":47,"value":6413},{"type":41,"tag":1302,"props":6562,"children":6563},{"style":6399},[6564],{"type":47,"value":6565}," )",{"type":41,"tag":1302,"props":6567,"children":6569},{"style":6568},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[6570],{"type":47,"value":6571}," =>",{"type":41,"tag":1302,"props":6573,"children":6574},{"style":6399},[6575],{"type":47,"value":6576}," {\n",{"type":41,"tag":1302,"props":6578,"children":6579},{"class":1304,"line":1359},[6580],{"type":41,"tag":1302,"props":6581,"children":6583},{"style":6582},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[6584],{"type":47,"value":6585},"        \u002F\u002F Match on your ability id, not on `assistant.slug`. An entry slug is\n",{"type":41,"tag":1302,"props":6587,"children":6588},{"class":1304,"line":1368},[6589],{"type":41,"tag":1302,"props":6590,"children":6591},{"style":6582},[6592],{"type":47,"value":6593},"        \u002F\u002F derived, and only a manifest controls its own: an agent with no\n",{"type":41,"tag":1302,"props":6595,"children":6596},{"class":1304,"line":1377},[6597],{"type":41,"tag":1302,"props":6598,"children":6599},{"style":6582},[6600],{"type":47,"value":6601},"        \u002F\u002F manifest gets a slug built from its whole ability id\n",{"type":41,"tag":1302,"props":6603,"children":6604},{"class":1304,"line":1386},[6605],{"type":41,"tag":1302,"props":6606,"children":6607},{"style":6582},[6608],{"type":47,"value":6609},"        \u002F\u002F (`workflow-{name}-{slug}`), so a slug comparison silently stops\n",{"type":41,"tag":1302,"props":6611,"children":6612},{"class":1304,"line":1395},[6613],{"type":41,"tag":1302,"props":6614,"children":6615},{"style":6582},[6616],{"type":47,"value":6617},"        \u002F\u002F matching. Ability ids are yours and never change under you.\n",{"type":41,"tag":1302,"props":6619,"children":6620},{"class":1304,"line":1405},[6621,6626,6632,6637,6641,6645,6650,6655,6660,6665,6669,6674,6678,6683],{"type":41,"tag":1302,"props":6622,"children":6623},{"style":6393},[6624],{"type":47,"value":6625},"        if",{"type":41,"tag":1302,"props":6627,"children":6629},{"style":6628},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[6630],{"type":47,"value":6631}," ( ",{"type":41,"tag":1302,"props":6633,"children":6634},{"style":6399},[6635],{"type":47,"value":6636},"!",{"type":41,"tag":1302,"props":6638,"children":6639},{"style":6405},[6640],{"type":47,"value":6525},{"type":41,"tag":1302,"props":6642,"children":6643},{"style":6399},[6644],{"type":47,"value":971},{"type":41,"tag":1302,"props":6646,"children":6647},{"style":6405},[6648],{"type":47,"value":6649},"ability_ids",{"type":41,"tag":1302,"props":6651,"children":6652},{"style":6399},[6653],{"type":47,"value":6654},"?.",{"type":41,"tag":1302,"props":6656,"children":6657},{"style":6452},[6658],{"type":47,"value":6659},"includes",{"type":41,"tag":1302,"props":6661,"children":6662},{"style":6628},[6663],{"type":47,"value":6664},"( ",{"type":41,"tag":1302,"props":6666,"children":6667},{"style":6399},[6668],{"type":47,"value":6434},{"type":41,"tag":1302,"props":6670,"children":6671},{"style":6426},[6672],{"type":47,"value":6673},"workflow-{name}\u002F{slug}",{"type":41,"tag":1302,"props":6675,"children":6676},{"style":6399},[6677],{"type":47,"value":6434},{"type":41,"tag":1302,"props":6679,"children":6680},{"style":6628},[6681],{"type":47,"value":6682}," ) ) ",{"type":41,"tag":1302,"props":6684,"children":6685},{"style":6399},[6686],{"type":47,"value":6687},"{\n",{"type":41,"tag":1302,"props":6689,"children":6690},{"class":1304,"line":1414},[6691,6696,6700],{"type":41,"tag":1302,"props":6692,"children":6693},{"style":6393},[6694],{"type":47,"value":6695},"            return",{"type":41,"tag":1302,"props":6697,"children":6698},{"style":6405},[6699],{"type":47,"value":6515},{"type":41,"tag":1302,"props":6701,"children":6702},{"style":6399},[6703],{"type":47,"value":6439},{"type":41,"tag":1302,"props":6705,"children":6706},{"class":1304,"line":1422},[6707],{"type":41,"tag":1302,"props":6708,"children":6709},{"style":6399},[6710],{"type":47,"value":2220},{"type":41,"tag":1302,"props":6712,"children":6713},{"class":1304,"line":1431},[6714],{"type":41,"tag":1302,"props":6715,"children":6716},{"emptyLinePlaceholder":1399},[6717],{"type":47,"value":1402},{"type":41,"tag":1302,"props":6719,"children":6720},{"class":1304,"line":1439},[6721,6726],{"type":41,"tag":1302,"props":6722,"children":6723},{"style":6393},[6724],{"type":47,"value":6725},"        return",{"type":41,"tag":1302,"props":6727,"children":6728},{"style":6628},[6729],{"type":47,"value":6730}," (\n",{"type":41,"tag":1302,"props":6732,"children":6733},{"class":1304,"line":1448},[6734,6739],{"type":41,"tag":1302,"props":6735,"children":6736},{"style":6399},[6737],{"type":47,"value":6738},"            \u003C",{"type":41,"tag":1302,"props":6740,"children":6742},{"style":6741},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[6743],{"type":47,"value":6744},"SettingsForm\n",{"type":41,"tag":1302,"props":6746,"children":6747},{"class":1304,"line":1457},[6748,6753,6758,6763],{"type":41,"tag":1302,"props":6749,"children":6750},{"style":6568},[6751],{"type":47,"value":6752},"                assistant",{"type":41,"tag":1302,"props":6754,"children":6755},{"style":6399},[6756],{"type":47,"value":6757},"={",{"type":41,"tag":1302,"props":6759,"children":6760},{"style":6405},[6761],{"type":47,"value":6762}," assistant ",{"type":41,"tag":1302,"props":6764,"children":6765},{"style":6399},[6766],{"type":47,"value":1463},{"type":41,"tag":1302,"props":6768,"children":6769},{"class":1304,"line":1466},[6770,6775,6779,6784],{"type":41,"tag":1302,"props":6771,"children":6772},{"style":6568},[6773],{"type":47,"value":6774},"                disabled",{"type":41,"tag":1302,"props":6776,"children":6777},{"style":6399},[6778],{"type":47,"value":6757},{"type":41,"tag":1302,"props":6780,"children":6781},{"style":6405},[6782],{"type":47,"value":6783}," disabled ",{"type":41,"tag":1302,"props":6785,"children":6786},{"style":6399},[6787],{"type":47,"value":1463},{"type":41,"tag":1302,"props":6789,"children":6790},{"class":1304,"line":1474},[6791,6796,6800,6805],{"type":41,"tag":1302,"props":6792,"children":6793},{"style":6568},[6794],{"type":47,"value":6795},"                onHasChangesChange",{"type":41,"tag":1302,"props":6797,"children":6798},{"style":6399},[6799],{"type":47,"value":6757},{"type":41,"tag":1302,"props":6801,"children":6802},{"style":6405},[6803],{"type":47,"value":6804}," onHasChangesChange ",{"type":41,"tag":1302,"props":6806,"children":6807},{"style":6399},[6808],{"type":47,"value":1463},{"type":41,"tag":1302,"props":6810,"children":6811},{"class":1304,"line":1483},[6812,6817,6821,6826],{"type":41,"tag":1302,"props":6813,"children":6814},{"style":6568},[6815],{"type":47,"value":6816},"                onSaveRef",{"type":41,"tag":1302,"props":6818,"children":6819},{"style":6399},[6820],{"type":47,"value":6757},{"type":41,"tag":1302,"props":6822,"children":6823},{"style":6405},[6824],{"type":47,"value":6825}," onSaveRef ",{"type":41,"tag":1302,"props":6827,"children":6828},{"style":6399},[6829],{"type":47,"value":1463},{"type":41,"tag":1302,"props":6831,"children":6832},{"class":1304,"line":1491},[6833],{"type":41,"tag":1302,"props":6834,"children":6835},{"style":6399},[6836],{"type":47,"value":6837},"            \u002F>\n",{"type":41,"tag":1302,"props":6839,"children":6840},{"class":1304,"line":1500},[6841,6846],{"type":41,"tag":1302,"props":6842,"children":6843},{"style":6628},[6844],{"type":47,"value":6845},"        )",{"type":41,"tag":1302,"props":6847,"children":6848},{"style":6399},[6849],{"type":47,"value":6439},{"type":41,"tag":1302,"props":6851,"children":6852},{"class":1304,"line":1509},[6853],{"type":41,"tag":1302,"props":6854,"children":6855},{"style":6399},[6856],{"type":47,"value":1524},{"type":41,"tag":1302,"props":6858,"children":6859},{"class":1304,"line":1518},[6860,6864],{"type":41,"tag":1302,"props":6861,"children":6862},{"style":6405},[6863],{"type":47,"value":296},{"type":41,"tag":1302,"props":6865,"children":6866},{"style":6399},[6867],{"type":47,"value":6439},{"type":41,"tag":50,"props":6869,"children":6870},{},[6871,6873,6879,6880,6886,6887,6892,6893,6899,6900,6906,6907,6912,6914,6920],{"type":47,"value":6872},"The filter receives the full unified agent entry (",{"type":41,"tag":125,"props":6874,"children":6876},{"className":6875},[],[6877],{"type":47,"value":6878},"slug",{"type":47,"value":909},{"type":41,"tag":125,"props":6881,"children":6883},{"className":6882},[],[6884],{"type":47,"value":6885},"capabilities",{"type":47,"value":909},{"type":41,"tag":125,"props":6888,"children":6890},{"className":6889},[],[6891],{"type":47,"value":6649},{"type":47,"value":909},{"type":41,"tag":125,"props":6894,"children":6896},{"className":6895},[],[6897],{"type":47,"value":6898},"provider_slugs",{"type":47,"value":909},{"type":41,"tag":125,"props":6901,"children":6903},{"className":6902},[],[6904],{"type":47,"value":6905},"options",{"type":47,"value":909},{"type":41,"tag":125,"props":6908,"children":6910},{"className":6909},[],[6911],{"type":47,"value":961},{"type":47,"value":6913},", …) plus a callbacks object. The card always passes that object, on every path, so destructure it directly — it is never ",{"type":41,"tag":125,"props":6915,"children":6917},{"className":6916},[],[6918],{"type":47,"value":6919},"undefined",{"type":47,"value":6921},". It carries three members:",{"type":41,"tag":71,"props":6923,"children":6924},{},[6925,6943,6954],{"type":41,"tag":75,"props":6926,"children":6927},{},[6928,6934,6935,6941],{"type":41,"tag":125,"props":6929,"children":6931},{"className":6930},[],[6932],{"type":47,"value":6933},"disabled",{"type":47,"value":1137},{"type":41,"tag":125,"props":6936,"children":6938},{"className":6937},[],[6939],{"type":47,"value":6940},"bool",{"type":47,"value":6942},") — the agent is switched off.",{"type":41,"tag":75,"props":6944,"children":6945},{},[6946,6952],{"type":41,"tag":125,"props":6947,"children":6949},{"className":6948},[],[6950],{"type":47,"value":6951},"onHasChangesChange( bool )",{"type":47,"value":6953}," — drives the Save button's enabled state.",{"type":41,"tag":75,"props":6955,"children":6956},{},[6957,6963],{"type":41,"tag":125,"props":6958,"children":6960},{"className":6959},[],[6961],{"type":47,"value":6962},"onSaveRef( fn )",{"type":47,"value":6964}," — registers a handler invoked when the user clicks Save.",{"type":41,"tag":50,"props":6966,"children":6967},{},[6968,6979,6981,6986,6988,6993,6995,7001],{"type":41,"tag":56,"props":6969,"children":6970},{},[6971,6973,6978],{"type":47,"value":6972},"You must honor ",{"type":41,"tag":125,"props":6974,"children":6976},{"className":6975},[],[6977],{"type":47,"value":6933},{"type":47,"value":971},{"type":47,"value":6980}," Everything your component renders describes how the agent behaves when it runs, so a switched-off agent offers none of it: pass ",{"type":41,"tag":125,"props":6982,"children":6984},{"className":6983},[],[6985],{"type":47,"value":6933},{"type":47,"value":6987}," to every control, and never report ",{"type":41,"tag":125,"props":6989,"children":6991},{"className":6990},[],[6992],{"type":47,"value":5725},{"type":47,"value":6994}," through ",{"type":41,"tag":125,"props":6996,"children":6998},{"className":6997},[],[6999],{"type":47,"value":7000},"onHasChangesChange",{"type":47,"value":7002}," while it is set. The card can only switch off the controls it renders itself, and your component replaces those outright — a component that ignores the flag lets a reader configure and save an agent that never runs, which is exactly the bug the flag exists to close. The Enabled toggle stays live; it is the way back.",{"type":41,"tag":50,"props":7004,"children":7005},{},[7006,7008,7014,7015,7021,7023,7029,7030,7036,7037,7043],{"type":47,"value":7007},"Settings persist via ",{"type":41,"tag":125,"props":7009,"children":7011},{"className":7010},[],[7012],{"type":47,"value":7013},"POST \u002Fvip-workflows\u002Fv1\u002Fassistants\u002F{slug}\u002Fsettings",{"type":47,"value":526},{"type":41,"tag":125,"props":7016,"children":7018},{"className":7017},[],[7019],{"type":47,"value":7020},"{ enabled?: bool, options?: object }",{"type":47,"value":7022},". The registry writes through to the underlying legacy options (",{"type":41,"tag":125,"props":7024,"children":7026},{"className":7025},[],[7027],{"type":47,"value":7028},"vip_workflows_ability_settings[ability_id]",{"type":47,"value":909},{"type":41,"tag":125,"props":7031,"children":7033},{"className":7032},[],[7034],{"type":47,"value":7035},"vip_discovery_provider_settings",{"type":47,"value":909},{"type":41,"tag":125,"props":7038,"children":7040},{"className":7039},[],[7041],{"type":47,"value":7042},"vip_discovery_provider_{slug}",{"type":47,"value":7044},"), so existing consumers keep working unchanged.",{"type":41,"tag":50,"props":7046,"children":7047},{},[7048,7050,7056,7058,7064,7066,7071,7073,7078,7080,7085,7087,7093],{"type":47,"value":7049},"The legacy ",{"type":41,"tag":125,"props":7051,"children":7053},{"className":7052},[],[7054],{"type":47,"value":7055},"vipWorkflows.assistantSettingsComponent",{"type":47,"value":7057}," (research) and ",{"type":41,"tag":125,"props":7059,"children":7061},{"className":7060},[],[7062],{"type":47,"value":7063},"vip_workflows_discovery_provider_settings",{"type":47,"value":7065}," (discovery) filters are still honored for backward compatibility, but new code should always use ",{"type":41,"tag":125,"props":7067,"children":7069},{"className":7068},[],[7070],{"type":47,"value":6473},{"type":47,"value":7072},". Both carry the same obligation: the legacy assistants filter receives the same three-member callbacks object, and the legacy discovery filter returns a component ",{"type":41,"tag":86,"props":7074,"children":7075},{},[7076],{"type":47,"value":7077},"type",{"type":47,"value":7079}," that the card renders with a ",{"type":41,"tag":125,"props":7081,"children":7083},{"className":7082},[],[7084],{"type":47,"value":6933},{"type":47,"value":7086}," prop alongside ",{"type":41,"tag":125,"props":7088,"children":7090},{"className":7089},[],[7091],{"type":47,"value":7092},"providerSlug",{"type":47,"value":971},{"type":41,"tag":134,"props":7095,"children":7097},{"id":7096},"caching",[7098],{"type":47,"value":7099},"Caching",{"type":41,"tag":50,"props":7101,"children":7102},{},[7103],{"type":47,"value":7104},"Cache external API responses server-side using WordPress transients:",{"type":41,"tag":71,"props":7106,"children":7107},{},[7108,7113,7118,7123,7128],{"type":41,"tag":75,"props":7109,"children":7110},{},[7111],{"type":47,"value":7112},"Research search results: 5–15 min TTL (keyed by query)",{"type":41,"tag":75,"props":7114,"children":7115},{},[7116],{"type":47,"value":7117},"Discovery recommendations: 15–30 min TTL",{"type":41,"tag":75,"props":7119,"children":7120},{},[7121],{"type":47,"value":7122},"Discovery search results: 5–10 min TTL (keyed by query + filters hash)",{"type":41,"tag":75,"props":7124,"children":7125},{},[7126],{"type":47,"value":7127},"Filter definitions: 24 hour TTL (taxonomy data changes rarely)",{"type":41,"tag":75,"props":7129,"children":7130},{},[7131],{"type":47,"value":7132},"Auth tokens: cache until expiry minus a buffer",{"type":41,"tag":134,"props":7134,"children":7136},{"id":7135},"registration-rules",[7137],{"type":47,"value":7138},"Registration Rules",{"type":41,"tag":50,"props":7140,"children":7141},{},[7142],{"type":41,"tag":56,"props":7143,"children":7144},{},[7145],{"type":47,"value":7146},"Research ability:",{"type":41,"tag":71,"props":7148,"children":7149},{},[7150,7167,7184,7199,7214,7233],{"type":41,"tag":75,"props":7151,"children":7152},{},[7153,7155,7159,7161],{"type":47,"value":7154},"Ability name ",{"type":41,"tag":56,"props":7156,"children":7157},{},[7158],{"type":47,"value":2661},{"type":47,"value":7160}," be namespaced: ",{"type":41,"tag":125,"props":7162,"children":7164},{"className":7163},[],[7165],{"type":47,"value":7166},"plugin-slug\u002Fability-slug",{"type":41,"tag":75,"props":7168,"children":7169},{},[7170,7176,7178],{"type":41,"tag":125,"props":7171,"children":7173},{"className":7172},[],[7174],{"type":47,"value":7175},"category",{"type":47,"value":7177}," must be ",{"type":41,"tag":125,"props":7179,"children":7181},{"className":7180},[],[7182],{"type":47,"value":7183},"'research'",{"type":41,"tag":75,"props":7185,"children":7186},{},[7187,7193,7194],{"type":41,"tag":125,"props":7188,"children":7190},{"className":7189},[],[7191],{"type":47,"value":7192},"meta.type",{"type":47,"value":7177},{"type":41,"tag":125,"props":7195,"children":7197},{"className":7196},[],[7198],{"type":47,"value":7183},{"type":41,"tag":75,"props":7200,"children":7201},{},[7202,7208,7209],{"type":41,"tag":125,"props":7203,"children":7205},{"className":7204},[],[7206],{"type":47,"value":7207},"meta.show_in_rest",{"type":47,"value":7177},{"type":41,"tag":125,"props":7210,"children":7212},{"className":7211},[],[7213],{"type":47,"value":5725},{"type":41,"tag":75,"props":7215,"children":7216},{},[7217,7219,7224,7226,7232],{"type":47,"value":7218},"Hook into ",{"type":41,"tag":125,"props":7220,"children":7222},{"className":7221},[],[7223],{"type":47,"value":216},{"type":47,"value":7225}," (not ",{"type":41,"tag":125,"props":7227,"children":7229},{"className":7228},[],[7230],{"type":47,"value":7231},"init",{"type":47,"value":296},{"type":41,"tag":75,"props":7234,"children":7235},{},[7236,7238,7244],{"type":47,"value":7237},"Guard with ",{"type":41,"tag":125,"props":7239,"children":7241},{"className":7240},[],[7242],{"type":47,"value":7243},"function_exists( 'vip_workflows_register_ability' )",{"type":47,"value":7245}," so the plugin degrades gracefully",{"type":41,"tag":50,"props":7247,"children":7248},{},[7249],{"type":41,"tag":56,"props":7250,"children":7251},{},[7252],{"type":47,"value":7253},"Discovery provider:",{"type":41,"tag":71,"props":7255,"children":7256},{},[7257,7262,7285,7304,7328,7340,7351],{"type":41,"tag":75,"props":7258,"children":7259},{},[7260],{"type":47,"value":7261},"Provider slug must be unique across all plugins",{"type":41,"tag":75,"props":7263,"children":7264},{},[7265,7270,7272,7278,7280],{"type":41,"tag":125,"props":7266,"children":7268},{"className":7267},[],[7269],{"type":47,"value":348},{"type":47,"value":7271}," must contain ",{"type":41,"tag":125,"props":7273,"children":7275},{"className":7274},[],[7276],{"type":47,"value":7277},"'recommend'",{"type":47,"value":7279}," and\u002For ",{"type":41,"tag":125,"props":7281,"children":7283},{"className":7282},[],[7284],{"type":47,"value":1064},{"type":41,"tag":75,"props":7286,"children":7287},{},[7288,7290,7295,7297,7302],{"type":47,"value":7289},"If ",{"type":41,"tag":125,"props":7291,"children":7293},{"className":7292},[],[7294],{"type":47,"value":271},{"type":47,"value":7296}," is declared, the ",{"type":41,"tag":125,"props":7298,"children":7300},{"className":7299},[],[7301],{"type":47,"value":271},{"type":47,"value":7303}," callback must be callable",{"type":41,"tag":75,"props":7305,"children":7306},{},[7307,7308,7313,7315,7320,7321,7326],{"type":47,"value":7289},{"type":41,"tag":125,"props":7309,"children":7311},{"className":7310},[],[7312],{"type":47,"value":279},{"type":47,"value":7314}," is declared, both ",{"type":41,"tag":125,"props":7316,"children":7318},{"className":7317},[],[7319],{"type":47,"value":279},{"type":47,"value":1106},{"type":41,"tag":125,"props":7322,"children":7324},{"className":7323},[],[7325],{"type":47,"value":287},{"type":47,"value":7327}," callbacks must be callable",{"type":41,"tag":75,"props":7329,"children":7330},{},[7331,7333,7338],{"type":47,"value":7332},"The ",{"type":41,"tag":125,"props":7334,"children":7336},{"className":7335},[],[7337],{"type":47,"value":263},{"type":47,"value":7339}," callback is always required",{"type":41,"tag":75,"props":7341,"children":7342},{},[7343,7344,7349],{"type":47,"value":7218},{"type":41,"tag":125,"props":7345,"children":7347},{"className":7346},[],[7348],{"type":47,"value":254},{"type":47,"value":7350}," (receives the registry instance)",{"type":41,"tag":75,"props":7352,"children":7353},{},[7354,7359,7361,7366,7368,7373,7375],{"type":41,"tag":125,"props":7355,"children":7357},{"className":7356},[],[7358],{"type":47,"value":1112},{"type":47,"value":7360}," is optional; if omitted the provider is always considered available. When present it should return ",{"type":41,"tag":125,"props":7362,"children":7364},{"className":7363},[],[7365],{"type":47,"value":5725},{"type":47,"value":7367}," or an ",{"type":41,"tag":125,"props":7369,"children":7371},{"className":7370},[],[7372],{"type":47,"value":1167},{"type":47,"value":7374}," — see ",{"type":41,"tag":1162,"props":7376,"children":7377},{"href":1164},[7378],{"type":47,"value":1167},{"type":41,"tag":50,"props":7380,"children":7381},{},[7382],{"type":41,"tag":56,"props":7383,"children":7384},{},[7385],{"type":47,"value":7386},"Unified manifest (multi-capability plugins):",{"type":41,"tag":71,"props":7388,"children":7389},{},[7390,7400,7410,7420,7437],{"type":41,"tag":75,"props":7391,"children":7392},{},[7393,7398],{"type":41,"tag":125,"props":7394,"children":7396},{"className":7395},[],[7397],{"type":47,"value":6878},{"type":47,"value":7399}," must match the plugin's directory\u002Ftext-domain slug",{"type":41,"tag":75,"props":7401,"children":7402},{},[7403,7408],{"type":41,"tag":125,"props":7404,"children":7406},{"className":7405},[],[7407],{"type":47,"value":6649},{"type":47,"value":7409}," must reference abilities the plugin actually registers",{"type":41,"tag":75,"props":7411,"children":7412},{},[7413,7418],{"type":41,"tag":125,"props":7414,"children":7416},{"className":7415},[],[7417],{"type":47,"value":6898},{"type":47,"value":7419}," must reference providers the plugin actually registers",{"type":41,"tag":75,"props":7421,"children":7422},{},[7423,7428,7430,7435],{"type":41,"tag":125,"props":7424,"children":7426},{"className":7425},[],[7427],{"type":47,"value":6885},{"type":47,"value":7429}," may include ",{"type":41,"tag":125,"props":7431,"children":7433},{"className":7432},[],[7434],{"type":47,"value":482},{"type":47,"value":7436}," when the plugin has at least one registered stage-eligible ability; the registry ignores unsupported manifest claims",{"type":41,"tag":75,"props":7438,"children":7439},{},[7440,7441,7446],{"type":47,"value":7218},{"type":41,"tag":125,"props":7442,"children":7444},{"className":7443},[],[7445],{"type":47,"value":524},{"type":47,"value":7350},{"type":41,"tag":50,"props":7448,"children":7449},{},[7450],{"type":41,"tag":56,"props":7451,"children":7452},{},[7453],{"type":47,"value":7454},"Stage ability:",{"type":41,"tag":71,"props":7456,"children":7457},{},[7458,7472,7488,7503,7524,7539,7555,7596,7607,7625],{"type":41,"tag":75,"props":7459,"children":7460},{},[7461,7462,7466,7467],{"type":47,"value":7154},{"type":41,"tag":56,"props":7463,"children":7464},{},[7465],{"type":47,"value":2661},{"type":47,"value":7160},{"type":41,"tag":125,"props":7468,"children":7470},{"className":7469},[],[7471],{"type":47,"value":7166},{"type":41,"tag":75,"props":7473,"children":7474},{},[7475,7480,7482],{"type":41,"tag":125,"props":7476,"children":7478},{"className":7477},[],[7479],{"type":47,"value":7175},{"type":47,"value":7481}," should be ",{"type":41,"tag":125,"props":7483,"children":7485},{"className":7484},[],[7486],{"type":47,"value":7487},"'vip-workflows'",{"type":41,"tag":75,"props":7489,"children":7490},{},[7491,7496,7497],{"type":41,"tag":125,"props":7492,"children":7494},{"className":7493},[],[7495],{"type":47,"value":7192},{"type":47,"value":7177},{"type":41,"tag":125,"props":7498,"children":7500},{"className":7499},[],[7501],{"type":47,"value":7502},"'agent'",{"type":41,"tag":75,"props":7504,"children":7505},{},[7506,7511,7513,7518,7519],{"type":41,"tag":125,"props":7507,"children":7509},{"className":7508},[],[7510],{"type":47,"value":490},{"type":47,"value":7512}," must include both ",{"type":41,"tag":125,"props":7514,"children":7516},{"className":7515},[],[7517],{"type":47,"value":498},{"type":47,"value":1106},{"type":41,"tag":125,"props":7520,"children":7522},{"className":7521},[],[7523],{"type":47,"value":482},{"type":41,"tag":75,"props":7525,"children":7526},{},[7527,7533,7534],{"type":41,"tag":125,"props":7528,"children":7530},{"className":7529},[],[7531],{"type":47,"value":7532},"meta.stage_eligible",{"type":47,"value":7177},{"type":41,"tag":125,"props":7535,"children":7537},{"className":7536},[],[7538],{"type":47,"value":5725},{"type":41,"tag":75,"props":7540,"children":7541},{},[7542,7548,7550],{"type":41,"tag":125,"props":7543,"children":7545},{"className":7544},[],[7546],{"type":47,"value":7547},"input_schema",{"type":47,"value":7549}," must require ",{"type":41,"tag":125,"props":7551,"children":7553},{"className":7552},[],[7554],{"type":47,"value":448},{"type":41,"tag":75,"props":7556,"children":7557},{},[7558,7564,7565,7570,7571,7576,7578,7583,7585,7590,7591],{"type":41,"tag":125,"props":7559,"children":7561},{"className":7560},[],[7562],{"type":47,"value":7563},"output_schema",{"type":47,"value":7549},{"type":41,"tag":125,"props":7566,"children":7568},{"className":7567},[],[7569],{"type":47,"value":565},{"type":47,"value":1106},{"type":41,"tag":125,"props":7572,"children":7574},{"className":7573},[],[7575],{"type":47,"value":603},{"type":47,"value":7577},", with ",{"type":41,"tag":125,"props":7579,"children":7581},{"className":7580},[],[7582],{"type":47,"value":565},{"type":47,"value":7584}," limited to ",{"type":41,"tag":125,"props":7586,"children":7588},{"className":7587},[],[7589],{"type":47,"value":573},{"type":47,"value":1106},{"type":41,"tag":125,"props":7592,"children":7594},{"className":7593},[],[7595],{"type":47,"value":581},{"type":41,"tag":75,"props":7597,"children":7598},{},[7599,7600,7605],{"type":47,"value":7218},{"type":41,"tag":125,"props":7601,"children":7603},{"className":7602},[],[7604],{"type":47,"value":329},{"type":47,"value":7606}," so core stage helpers are already loaded",{"type":41,"tag":75,"props":7608,"children":7609},{},[7610,7612,7617,7618,7623],{"type":47,"value":7611},"Register a manifest on ",{"type":41,"tag":125,"props":7613,"children":7615},{"className":7614},[],[7616],{"type":47,"value":524},{"type":47,"value":526},{"type":41,"tag":125,"props":7619,"children":7621},{"className":7620},[],[7622],{"type":47,"value":532},{"type":47,"value":7624}," so the Agents card is marked available in AI stages when the ability metadata also qualifies",{"type":41,"tag":75,"props":7626,"children":7627},{},[7628,7630,7635,7637,7642,7644,7649,7651],{"type":47,"value":7629},"Read-only agents should declare ",{"type":41,"tag":125,"props":7631,"children":7633},{"className":7632},[],[7634],{"type":47,"value":645},{"type":47,"value":7636},"; mutating agents must write through ",{"type":41,"tag":125,"props":7638,"children":7640},{"className":7639},[],[7641],{"type":47,"value":661},{"type":47,"value":7643}," (rewrite the body) or ",{"type":41,"tag":125,"props":7645,"children":7647},{"className":7646},[],[7648],{"type":47,"value":669},{"type":47,"value":7650}," (attach native block notes), and declare ",{"type":41,"tag":125,"props":7652,"children":7654},{"className":7653},[],[7655],{"type":47,"value":693},{"type":41,"tag":134,"props":7657,"children":7659},{"id":7658},"testing",[7660],{"type":47,"value":7661},"Testing",{"type":41,"tag":430,"props":7663,"children":7664},{},[7665,7676,7681,7692],{"type":41,"tag":75,"props":7666,"children":7667},{},[7668,7670,7675],{"type":47,"value":7669},"Place the plugin directory alongside ",{"type":41,"tag":125,"props":7671,"children":7673},{"className":7672},[],[7674],{"type":47,"value":1196},{"type":47,"value":971},{"type":41,"tag":75,"props":7677,"children":7678},{},[7679],{"type":47,"value":7680},"Activate it in WordPress admin.",{"type":41,"tag":75,"props":7682,"children":7683},{},[7684,7686,7690],{"type":47,"value":7685},"Go to ",{"type":41,"tag":56,"props":7687,"children":7688},{},[7689],{"type":47,"value":67},{"type":47,"value":7691}," to verify it appears as a single card and can be enabled.",{"type":41,"tag":75,"props":7693,"children":7694},{},[7695,7697],{"type":47,"value":7696},"Configure any settings, then:\n",{"type":41,"tag":71,"props":7698,"children":7699},{},[7700,7710,7720,7751,7778,7788,7798],{"type":41,"tag":75,"props":7701,"children":7702},{},[7703,7708],{"type":41,"tag":56,"props":7704,"children":7705},{},[7706],{"type":47,"value":7707},"Research:",{"type":47,"value":7709}," Create a new ideation project and confirm the agent runs on the mood board.",{"type":41,"tag":75,"props":7711,"children":7712},{},[7713,7718],{"type":41,"tag":56,"props":7714,"children":7715},{},[7716],{"type":47,"value":7717},"Stage:",{"type":47,"value":7719}," Open a Sequence, select a stage node, and confirm the agent appears in the inspector's Agent picker; choosing it turns the node purple and gives it the three outcome handles.",{"type":41,"tag":75,"props":7721,"children":7722},{},[7723,7727,7729,7735,7736,7741,7743,7749],{"type":41,"tag":56,"props":7724,"children":7725},{},[7726],{"type":47,"value":7717},{"type":47,"value":7728}," Drag each outcome handle onto a destination stage, then save and reload the Sequence to confirm ",{"type":41,"tag":125,"props":7730,"children":7732},{"className":7731},[],[7733],{"type":47,"value":7734},"agent.ability_id",{"type":47,"value":909},{"type":41,"tag":125,"props":7737,"children":7739},{"className":7738},[],[7740],{"type":47,"value":969},{"type":47,"value":7742},", and ",{"type":41,"tag":125,"props":7744,"children":7746},{"className":7745},[],[7747],{"type":47,"value":7748},"agent.routing",{"type":47,"value":7750}," persist.",{"type":41,"tag":75,"props":7752,"children":7753},{},[7754,7758,7760,7765,7766,7771,7772,7777],{"type":41,"tag":56,"props":7755,"children":7756},{},[7757],{"type":47,"value":7717},{"type":47,"value":7759}," Transition a post into the AI-owned stage and confirm the runner stores the result and routes by ",{"type":41,"tag":125,"props":7761,"children":7763},{"className":7762},[],[7764],{"type":47,"value":573},{"type":47,"value":909},{"type":41,"tag":125,"props":7767,"children":7769},{"className":7768},[],[7770],{"type":47,"value":581},{"type":47,"value":1006},{"type":41,"tag":125,"props":7773,"children":7775},{"className":7774},[],[7776],{"type":47,"value":627},{"type":47,"value":971},{"type":41,"tag":75,"props":7779,"children":7780},{},[7781,7786],{"type":41,"tag":56,"props":7782,"children":7783},{},[7784],{"type":47,"value":7785},"Discovery (recommend):",{"type":47,"value":7787}," Visit the Ideation landing page and confirm curated prompts appear.",{"type":41,"tag":75,"props":7789,"children":7790},{},[7791,7796],{"type":41,"tag":56,"props":7792,"children":7793},{},[7794],{"type":47,"value":7795},"Discovery (search):",{"type":47,"value":7797}," Click \"Browse more…\" to open the search modal and test queries + filters.",{"type":41,"tag":75,"props":7799,"children":7800},{},[7801,7806],{"type":41,"tag":56,"props":7802,"children":7803},{},[7804],{"type":47,"value":7805},"Discovery (prompt selection):",{"type":47,"value":7807}," Click a prompt and confirm a new project is created with the expected seed text.",{"type":41,"tag":7809,"props":7810,"children":7811},"style",{},[7812],{"type":47,"value":7813},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":7815,"total":1323},[7816,7822,7842],{"slug":4,"name":4,"fn":5,"description":6,"org":7817,"tags":7818,"stars":22,"repoUrl":23,"updatedAt":24},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7819,7820,7821],{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},{"name":13,"slug":14,"type":15},{"slug":7823,"name":7823,"fn":7824,"description":7825,"org":7826,"tags":7827,"stars":22,"repoUrl":23,"updatedAt":7841},"create-vip-workflows-notification-channel","scaffold VIP Workflows notification plugins","Scaffold a VIP Workflows notification channel plugin. Use when the user wants to add a custom notification destination like Slack, Teams, Discord, SMS, or any webhook-based service to VIP Workflows.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7828,7831,7834,7835,7838],{"name":7829,"slug":7830,"type":15},"Automation","automation",{"name":7832,"slug":7833,"type":15},"Microsoft Teams","microsoft-teams",{"name":17,"slug":18,"type":15},{"name":7836,"slug":7837,"type":15},"Slack","slack",{"name":7839,"slug":7840,"type":15},"Webhooks","webhooks","2026-09-04T08:00:43.363392",{"slug":7843,"name":7843,"fn":7844,"description":7845,"org":7846,"tags":7847,"stars":22,"repoUrl":23,"updatedAt":7853},"create-vip-workflows-tool","scaffold VIP Workflows editorial tools","Scaffold a VIP Workflows editorial tool plugin. Use when the user wants to create a custom content analysis tool, validator, or checker for VIP Workflows.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7848,7851,7852],{"name":7849,"slug":7850,"type":15},"Code Analysis","code-analysis",{"name":17,"slug":18,"type":15},{"name":13,"slug":14,"type":15},"2026-09-04T08:00:44.370747",{"items":7855,"total":2091},[7856,7877,7894,7908,7921,7938,7953,7965,7980,7997,8008,8023],{"slug":7857,"name":7857,"fn":7858,"description":7859,"org":7860,"tags":7861,"stars":7874,"repoUrl":7875,"updatedAt":7876},"annotate","collect visual feedback with browser annotation tools","Open a browser with visual annotation tools. The user clicks elements on their site and leaves feedback — the agent reads annotations and makes changes. Use this when the user wants to point at specific elements to fix, tweak, or redesign.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7862,7865,7868,7871],{"name":7863,"slug":7864,"type":15},"Frontend","frontend",{"name":7866,"slug":7867,"type":15},"Productivity","productivity",{"name":7869,"slug":7870,"type":15},"UX Copy","ux-copy",{"name":7872,"slug":7873,"type":15},"UX Design","ux-design",484,"https:\u002F\u002Fgithub.com\u002FAutomattic\u002Fstudio","2026-05-06T05:40:01.516544",{"slug":7878,"name":7878,"fn":7879,"description":7880,"org":7881,"tags":7882,"stars":7874,"repoUrl":7875,"updatedAt":7893},"block-content","write editable WordPress block markup","Write editable WordPress block markup for local Studio sites, including core\u002Fhtml limits, block-theme layout rules, full-width sections, validation, and skeleton-first page\u002FCSS recipes.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7883,7886,7889,7892],{"name":7884,"slug":7885,"type":15},"Block Editor","block-editor",{"name":7887,"slug":7888,"type":15},"CSS","css",{"name":7890,"slug":7891,"type":15},"HTML","html",{"name":13,"slug":14,"type":15},"2026-08-29T09:23:44.042569",{"slug":7895,"name":7895,"fn":7896,"description":7897,"org":7898,"tags":7899,"stars":7874,"repoUrl":7875,"updatedAt":7907},"hosting-plans-helper","provide WordPress.com hosting plan information","Answer WordPress.com plan, pricing, upgrade, and feature-tier questions (plan names, what each tier unlocks — plugins, themes, custom code, SSH, hosting — and current prices) from authoritative live data. Load before answering ANY plan, pricing, or feature-gating question; never answer these from memory.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7900,7903,7906],{"name":7901,"slug":7902,"type":15},"Pricing","pricing",{"name":7904,"slug":7905,"type":15},"Reference","reference",{"name":13,"slug":14,"type":15},"2026-07-02T07:42:33.654791",{"slug":7909,"name":7909,"fn":7910,"description":7911,"org":7912,"tags":7913,"stars":7874,"repoUrl":7875,"updatedAt":7920},"imagery","generate AI images for websites","Generate AI images for a site with generate_images — how to write image specs, pick aspect ratios, place files (theme assets vs media library), and handle failures.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7914,7917],{"name":7915,"slug":7916,"type":15},"Creative","creative",{"name":7918,"slug":7919,"type":15},"Image Generation","image-generation","2026-09-01T08:30:34.994105",{"slug":7922,"name":7922,"fn":7923,"description":7924,"org":7925,"tags":7926,"stars":7874,"repoUrl":7875,"updatedAt":7937},"liberate","migrate websites to WordPress","Import and rebuild a website from a closed platform (Wix, Squarespace, Webflow, Shopify, GoDaddy, Hostinger, HubSpot, Weebly) into a Studio WordPress site. Extracts pages\u002Fposts\u002Fproducts + media, then reconstructs the design as editable blocks + WooCommerce OR as a high-fidelity replica theme. Invoke when the user wants to migrate, import, liberate, or rebuild a site from one of these platforms.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7927,7930,7933,7936],{"name":7928,"slug":7929,"type":15},"CMS","cms",{"name":7931,"slug":7932,"type":15},"Migration","migration",{"name":7934,"slug":7935,"type":15},"Web Development","web-development",{"name":13,"slug":14,"type":15},"2026-07-09T06:47:33.454311",{"slug":7939,"name":7939,"fn":7940,"description":7941,"org":7942,"tags":7943,"stars":7874,"repoUrl":7875,"updatedAt":7952},"need-for-speed","run frontend performance audits for WordPress sites","Run a frontend performance audit on a WordPress site and get actionable optimization recommendations.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7944,7947,7948,7951],{"name":7945,"slug":7946,"type":15},"Audit","audit",{"name":7863,"slug":7864,"type":15},{"name":7949,"slug":7950,"type":15},"Performance","performance",{"name":13,"slug":14,"type":15},"2026-05-06T05:40:06.433267",{"slug":7954,"name":7954,"fn":7955,"description":7956,"org":7957,"tags":7958,"stars":7874,"repoUrl":7875,"updatedAt":7964},"plugin-recommendations","recommend WordPress plugins for site features","Choose recommended plugins and plugin-provided blocks for features core WordPress blocks do not cover - ecommerce (WooCommerce), forms and newsletters (Jetpack), online courses and quizzes (Sensei LMS), polls, surveys and ratings (Crowdsignal), spam protection (Akismet) - while keeping generated content editable and avoiding raw HTML fallbacks. Any request to sell products or build a shop, store, or storefront requires WooCommerce with products.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7959,7962,7963],{"name":7960,"slug":7961,"type":15},"Content Creation","content-creation",{"name":17,"slug":18,"type":15},{"name":13,"slug":14,"type":15},"2026-08-22T03:27:47.937007",{"slug":7966,"name":7966,"fn":7967,"description":7968,"org":7969,"tags":7970,"stars":7874,"repoUrl":7875,"updatedAt":7979},"rank-me-up","run on-page SEO audits for WordPress sites","Run an on-page SEO audit on a WordPress site and get actionable recommendations to improve search visibility.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7971,7972,7975,7978],{"name":7945,"slug":7946,"type":15},{"name":7973,"slug":7974,"type":15},"Marketing","marketing",{"name":7976,"slug":7977,"type":15},"SEO","seo",{"name":13,"slug":14,"type":15},"2026-05-06T05:40:05.196367",{"slug":7981,"name":7981,"fn":7982,"description":7983,"org":7984,"tags":7985,"stars":7874,"repoUrl":7875,"updatedAt":7996},"site-spec","gather specifications for new WordPress sites","Gather the site name and layout preference before building a WordPress site. Run this before creating any new site.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7986,7989,7992,7995],{"name":7987,"slug":7988,"type":15},"Design","design",{"name":7990,"slug":7991,"type":15},"Product Management","product-management",{"name":7993,"slug":7994,"type":15},"Specs","specs",{"name":13,"slug":14,"type":15},"2026-05-06T05:40:02.739409",{"slug":7998,"name":7998,"fn":7999,"description":8000,"org":8001,"tags":8002,"stars":7874,"repoUrl":7875,"updatedAt":8007},"studio-cli","manage local WordPress sites with Studio CLI","Use the Studio CLI to manage local WordPress sites, authentication, and preview sites. Invoke this skill when you need to run Studio CLI commands, manage sites, or troubleshoot site issues.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[8003,8006],{"name":8004,"slug":8005,"type":15},"CLI","cli",{"name":13,"slug":14,"type":15},"2026-09-04T07:24:24.148676",{"slug":8009,"name":8009,"fn":8010,"description":8011,"org":8012,"tags":8013,"stars":7874,"repoUrl":7875,"updatedAt":8022},"taxonomist","optimize WordPress category taxonomy","Analyze and optimize a WordPress site's category taxonomy. Exports all posts, uses AI to suggest an improved category structure — merging duplicates, retiring dead categories, creating missing ones, writing descriptions, and re-categorizing posts. Run this when the user wants to clean up or improve their categories.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[8014,8017,8020,8021],{"name":8015,"slug":8016,"type":15},"Content Strategy","content-strategy",{"name":8018,"slug":8019,"type":15},"Data Cleaning","data-cleaning",{"name":7976,"slug":7977,"type":15},{"name":13,"slug":14,"type":15},"2026-05-06T05:40:03.966799",{"slug":8024,"name":8024,"fn":8025,"description":8026,"org":8027,"tags":8028,"stars":7874,"repoUrl":7875,"updatedAt":8038},"visual-design","plan and execute visual design direction","Plan and execute high-quality visual direction for site creation, redesign, layout, typography, color, motion, and visual polish.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[8029,8032,8033,8036],{"name":8030,"slug":8031,"type":15},"Animation","animation",{"name":7987,"slug":7988,"type":15},{"name":8034,"slug":8035,"type":15},"Typography","typography",{"name":8037,"slug":8024,"type":15},"Visual Design","2026-07-24T05:40:57.887452"]