| @@ -403,8 +403,14 @@ | ||
| 403 | 403 | * @return array Response data |
| 404 | 404 | * @throws \Exception If request fails |
| 405 | 405 | */ |
| 406 | 406 | private function make_request(string $endpoint, array $body = []): array { |
| 407 | + // The user's daily ceiling and kill switch are enforced here, at the | |
| 408 | + // one place every outbound Claude call passes through, so no feature | |
| 409 | + // path can bypass them by forgetting to ask first (#448). | |
| 410 | + Spend_Guard::guard(); | |
| 411 | + Spend_Guard::record(); | |
| 412 | + | |
| 407 | 413 | $url = self::API_BASE_URL . '/' . ltrim($endpoint, '/'); |
| 408 | 414 | |
| 409 | 415 | $args = [ |
| 410 | 416 | 'timeout' => $this->timeout, |
| @@ -826,9 +832,9 @@ | ||
| 826 | 832 | return [ |
| 827 | 833 | 'optimized_data' => [ |
| 828 | 834 | 'site_name' => sanitize_text_field($optimization['optimized_data']['site_name'] ?? ''), |
| 829 | 835 | 'project_overview' => sanitize_textarea_field($optimization['optimized_data']['project_overview'] ?? ''), |
| 830 | - 'key_features' => sanitize_textarea_field($optimization['optimized_data']['key_features'] ?? ''), | |
| 836 | + 'key_features' => \ThinkRank\SEO\LLMs_Txt_Manager::normalize_ai_key_features($optimization['optimized_data']['key_features'] ?? ''), | |
| 831 | 837 | 'architecture' => sanitize_textarea_field($optimization['optimized_data']['architecture'] ?? ''), |
| 832 | 838 | 'development_guidelines' => sanitize_textarea_field($optimization['optimized_data']['development_guidelines'] ?? ''), |
| 833 | 839 | 'ai_context' => sanitize_textarea_field($optimization['optimized_data']['ai_context'] ?? ''), |
| 834 | 840 | ], |