Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d365292
init
davidperezgar Dec 13, 2025
ccbde91
finished settings page
davidperezgar Dec 13, 2025
947d189
namer page
davidperezgar Dec 13, 2025
9645f06
jslint
davidperezgar Dec 13, 2025
3761082
lint
davidperezgar Dec 13, 2025
c9b7d5f
phpstan
davidperezgar Dec 13, 2025
cc02419
Update team reference in plugin name evaluation doc
davidperezgar Dec 13, 2025
eaba50f
finished review
davidperezgar Dec 14, 2025
15e117e
fix lint
davidperezgar Dec 14, 2025
80a4485
Merge branch 'trunk' into 1124-feature-request-add-name-quality-checker
davidperezgar Dec 14, 2025
a1375d4
fix lint
davidperezgar Dec 14, 2025
b2bf690
double prompt for name checking
davidperezgar Dec 16, 2025
9a1c37a
fix lint
davidperezgar Dec 16, 2025
d595a31
fixes
davidperezgar Dec 16, 2025
1880605
Merge branch 'trunk' into 1124-feature-request-add-name-quality-checker
davidperezgar Dec 16, 2025
6b604be
fix lint
davidperezgar Dec 16, 2025
f824633
Update includes/Admin/Namer_Page.php
davidperezgar Dec 19, 2025
8fbf4ed
Merge branch 'trunk' into 1124-feature-request-add-name-quality-checker
davidperezgar Dec 19, 2025
48155e8
improved prompts
davidperezgar Dec 20, 2025
cc0479d
avoid Automattic flag as an spell error
davidperezgar Dec 20, 2025
708422b
Show tokens used
davidperezgar Dec 21, 2025
fc46361
fix lint
davidperezgar Dec 21, 2025
01dcab1
add model
davidperezgar Dec 21, 2025
1710afe
updated schema
davidperezgar Dec 24, 2025
8cf583a
finish checker
davidperezgar Dec 24, 2025
a42fb75
add author name to distinct trademarks
davidperezgar Dec 24, 2025
a4e578b
removed
davidperezgar Dec 24, 2025
b532ef0
fix lint
davidperezgar Dec 24, 2025
60408cb
Update prompts/ai-check-similar-name.md
davidperezgar Dec 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ extend-ignore-re = [
"wheres",
]

[default.extend-words]
Automattic = "Automattic"

[files]
extend-exclude = [
"includes/Lib/Readme/*.php"
Expand Down
72 changes: 72 additions & 0 deletions assets/css/plugin-check-admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,75 @@
.plugin-check__options #plugin-check__types-container {
margin-left: 40px;
}

/* JSON output formatting */
#plugin-check-namer-raw {
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
font-size: 13px;
line-height: 1.6;
background: #f6f7f7;
border: 1px solid #c3c4c7;
border-radius: 4px;
padding: 15px;
max-height: 600px;
overflow: auto;
color: #1d2327;
white-space: pre-wrap;
word-wrap: break-word;
}

/* Plugin Check Namer styles */
.plugin-check-namer-spinner {
float: none;
margin-left: 10px;
}

.plugin-check-namer-hidden {
display: none;
}

.plugin-check-namer-verdict-container {
margin-bottom: 20px;
padding: 15px;
background: #fff;
border-left: 4px solid #2271b1;
}

.plugin-check-namer-verdict-item {
margin: 0 0 10px 0;
}

.plugin-check-namer-meta {
margin: 0 0 5px 0;
color: #646970;
font-style: italic;
font-size: 0.9em;
}

.plugin-check-namer-tokens {
margin: 0;
}

.plugin-check-namer-confusion {
margin-top: 20px;
}

.plugin-check-namer-confusion-item {
margin-bottom: 15px;
padding: 10px;
background: #fff;
border-left: 4px solid #2271b1;
}

.plugin-check-namer-confusion-item-others {
border-left-color: #dba617;
}

.plugin-check-namer-confusion-meta {
color: #646970;
}

.plugin-check-namer-confusion-text {
color: #646970;
font-size: 0.9em;
}
157 changes: 157 additions & 0 deletions assets/js/admin-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/**
* Admin Settings JavaScript
*/

/* global pluginCheckSettings */

( function () {
'use strict';

document.addEventListener( 'DOMContentLoaded', function () {
const providerSelect = document.getElementById( 'ai_provider' );
const apiKeyInput = document.getElementById( 'ai_api_key' );
const modelSelect = document.getElementById( 'ai_model' );

if ( ! providerSelect || ! apiKeyInput || ! modelSelect ) {
return;
}

// Store the initially selected model value from the backend.
// This value should persist across AJAX reloads.
let savedModelValue = modelSelect.dataset.initialValue || '';
let isFirstLoad = true;

/**
* Updates field states based on provider selection.
*/
function updateFields() {
const provider = providerSelect.value;

if ( provider ) {
apiKeyInput.disabled = false;
modelSelect.disabled = false;
updateModelOptions( provider );
} else {
apiKeyInput.disabled = true;
modelSelect.disabled = true;
modelSelect.value = '';
savedModelValue = '';
}
}

/**
* Fetches and updates model options for the selected provider.
*
* @param {string} provider Provider key.
*/
function updateModelOptions( provider ) {
// Save current value before clearing (in case user changed it).
// BUT: Don't override savedModelValue on first load - use data-initial-value.
if (
! isFirstLoad &&
modelSelect.value &&
modelSelect.value !== ''
) {
savedModelValue = modelSelect.value;
}

// Show loading state.
modelSelect.disabled = true;
modelSelect.innerHTML =
'<option value="">' +
pluginCheckSettings.loadingText +
'</option>';

// Fetch models via AJAX.
const formData = new FormData();
formData.append( 'action', 'plugin_check_get_models' );
formData.append( 'nonce', pluginCheckSettings.nonce );
formData.append( 'provider', provider );
formData.append( 'api_key', apiKeyInput.value || '' );

fetch( pluginCheckSettings.ajaxUrl, {
method: 'POST',
credentials: 'same-origin',
body: formData,
} )
.then( function ( response ) {
return response.json();
} )
.then( function ( response ) {
modelSelect.innerHTML = '';

// Add default option.
const defaultOption = document.createElement( 'option' );
defaultOption.value = '';
defaultOption.textContent =
pluginCheckSettings.selectModelText;
modelSelect.appendChild( defaultOption );

if ( response.success && response.data ) {
let modelFound = false;

// Add model options.
Object.keys( response.data ).forEach( function ( key ) {
const option = document.createElement( 'option' );
option.value = key;
option.textContent = response.data[ key ];

// Check if this is the saved model value.
if ( savedModelValue === key ) {
option.selected = true;
modelFound = true;
}

modelSelect.appendChild( option );
} );

// If the saved model wasn't found in the list, clear it.
if ( ! modelFound && savedModelValue ) {
savedModelValue = '';
}
} else {
// Show no models message.
const noModelsOption =
document.createElement( 'option' );
noModelsOption.value = '';
noModelsOption.textContent =
pluginCheckSettings.noModelsText;
modelSelect.appendChild( noModelsOption );
}

modelSelect.disabled = false;

// Mark that we've completed the first load.
isFirstLoad = false;
} )
.catch( function ( error ) {
console.error( 'Error fetching models:', error );

modelSelect.innerHTML = '';
const errorOption = document.createElement( 'option' );
errorOption.value = '';
errorOption.textContent = pluginCheckSettings.errorText;
modelSelect.appendChild( errorOption );

modelSelect.disabled = false;

// Mark that we've completed the first load even on error.
isFirstLoad = false;
} );
}

// Bind events.
providerSelect.addEventListener( 'change', updateFields );
apiKeyInput.addEventListener( 'change', function () {
if ( providerSelect.value ) {
updateModelOptions( providerSelect.value );
}
} );
modelSelect.addEventListener( 'change', function () {
savedModelValue = modelSelect.value || '';
} );

// Initial update.
updateFields();
} );
} )();
Loading
Loading