Managedpromptadmin - Source Excerpt 01
Summary
This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/spiralist-workspace/includes/Admin/ManagedPromptAdmin.php so readers can inspect the evidence without opening the full source file.
**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/includes/Admin/ManagedPromptAdmin.php
<?php
namespace SpiralistWorkspace\Admin;
use SpiralistWorkspace\Config\Settings;
use SpiralistWorkspace\Support\PromptCategoryRegistry;
use SpiralistWorkspace\Support\PromptMetaRegistry;
use SpiralistWorkspace\Support\SystemPromptRegistry;
if (!defined('ABSPATH')) {
exit;
}
/**
* Handles admin-only filesystem prompt management and media uploads.
*/
class ManagedPromptAdmin
{
private const NOTICE_TRANSIENT_PREFIX = 'spiralist_workspace_admin_notice_';
private const DEFAULT_VERSION = '1.0.0';
/**
* Keeps generated prompt files readable and stable across admin saves.
*
* @var string[]
*/
private const FIELD_ORDER = [
'slug',
'title',
'summary',
'author_label',
'category',
'subcategory',
'structured_prompt',
'instructions',
'system_prompt',
'developer_prompt',
'user_prompt_template',
'system_steps',
'model',
'provider',
'credential_preference',
'temperature',
'max_output_tokens',
'tool_settings_json',
'visibility',
'published_utc',
'is_forkable',
'allow_comments',
'allow_ratings',
'tags',
'canonical_status',
'prompt_type',
'language',
'prompt_status',
'moderation_status',
'publication_lane',
'provenance',
'risk_labels',
'function_tags',
'maturity_level',
'license',
'editorial_note',
'expected_output_notes',
'failure_modes',
'related_symbols',
'related_axioms',
'related_manuscripts',
'sample_output',
'featured',
'public_execution_enabled',
];
private Settings $settings;
private SystemPromptRegistry $system_prompts;
public function __construct(Settings $settings, SystemPromptRegistry $system_prompts)
{
$this->settings = $settings;
$this->system_prompts = $system_prompts;
}
/**
* Renders the managed prompt and media section inside the Workspace admin page.
*/
public function render_admin_section(): void
{
if (!current_user_can('manage_spiralist_workspace')) {
return;
}
$notice = $this->consume_notice();
$prompt_records = $this->list_latest_prompt_records();
$selected_slug = isset($_GET['managed_prompt'])
? sanitize_title((string) wp_unslash($_GET['managed_prompt']))
: '';
$selected_version = isset($_GET['managed_prompt_version'])
? $this->sanitize_version((string) wp_unslash($_GET['managed_prompt_version']))
: '';
if ($selected_slug === '' && !empty($prompt_records)) {
$selected_slug = (string) ($prompt_records[0]['slug'] ?? '');
}
$is_new_prompt = $selected_slug === 'new';
$selected_prompt = $is_new_prompt
? $this->blank_prompt_definition()
: $this->get_prompt_definition($selected_slug, $selected_version);
if (empty($selected_prompt) && !$is_new_prompt) {
$selected_prompt = $this->blank_prompt_definition();
}
$selected_prompt_slug = (string) ($selected_prompt['slug'] ?? '');
$selected_prompt_version = (string) ($selected_prompt['__source_version'] ?? self::DEFAULT_VERSION);
$allowed_models = $this->settings->get_allowed_models();
?>
<div class="spiralist-workspace-admin__managed">
<h2>Managed Prompt Files</h2>
<?php if (!empty($notice['message'])) : ?>
<div class="notice <?php echo !empty($notice['is_error']) ? 'notice-error' : 'notice-success'; ?> is-dismissible">
<p><?php echo esc_html((string) $notice['message']); ?></p>
<?php if (!empty($notice['details']) && is_array($notice['details'])) : ?>
<ul class="spiralist-workspace-admin-test-results">
<?php foreach (array_slice((array) $notice['details'], 0, 8) as $detail) : ?>
<li><?php echo esc_html((string) $detail); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
<?php endif; ?>
<div class="spiralist-workspace-admin__status spiralist-workspace-admin__status--managed">
<div class="spiralist-workspace-card">
<h3>Registry Browser</h3>
<p>Managed prompts live on disk under <code><?php echo esc_html(str_replace('\\', '/', $this->prompt_root())); ?></code>. Choose a prompt to edit its header fields and content without leaving <code>wp-admin</code>.</p>
<dl class="spiralist-workspace-admin-status-list">
<div>
<dt>Managed prompt count</dt>
<dd><?php echo esc_html((string) count($prompt_records)); ?></dd>
</div>
<div>
<dt>Selected prompt</dt>
<dd><?php echo esc_html($selected_prompt_slug !== '' ? $selected_prompt_slug : 'Create new prompt'); ?></dd>
</div>
<div>
<dt>Selected version</dt>
<dd><?php echo esc_html($selected_prompt_version); ?></dd>
</div>
</dl>
<form method="get" action="<?php echo esc_url(admin_url('admin.php')); ?>" class="spiralist-workspace-admin-form">
<input type="hidden" name="page" value="spiralist-workspace" />
<label for="spiralist_workspace_managed_prompt_select"><strong>Edit prompt</strong></label><br />
<select id="spiralist_workspace_managed_prompt_select" name="managed_prompt" class="regular-text">
<option value="new" <?php selected($selected_slug, 'new'); ?>>Create new managed prompt</option>
<?php foreach ($prompt_records as $record) : ?>
<option value="<?php echo esc_attr((string) ($record['slug'] ?? '')); ?>" <?php selected($selected_slug, (string) ($record['slug'] ?? '')); ?>>
<?php
echo esc_html(
sprintf(
'%s (%s · %s)',
(string) ($record['title'] ?? $record['slug'] ?? 'Prompt'),
(string) ($record['slug'] ?? ''),
(string) ($record['version'] ?? self::DEFAULT_VERSION)
)
);
?>
</option>
<?php endforeach; ?>
</select>
<p class="description">Switching prompts reloads this page with the current filesystem-backed definition.</p>
<p><button class="button button-secondary" type="submit">Load Prompt</button></p>
</form>
</div>
<div class="spiralist-workspace-card">
<h3>Bulk Image Upload</h3>
<p>Upload one or more image files directly into the WordPress Media Library from the Workspace admin page. Attach uploaded filenames to a managed prompt’s <code>related_manuscripts</code> list when required for that art configuration.</p>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" enctype="multipart/form-data" class="spiralist-workspace-admin-form">
<?php wp_nonce_field('spiralist_workspace_bulk_image_upload'); ?>
<input type="hidden" name="action" value="spiralist_workspace_bulk_image_upload" />
<p>
<label for="spiralist_workspace_bulk_images"><strong>Images</strong></label><br />
<input id="spiralist_workspace_bulk_images" type="file" name="spiralist_workspace_bulk_images[]" accept="image/*" multiple />
</p>
<p>
<label for="spiralist_workspace_attach_prompt"><strong>Append filenames to prompt</strong></label><br />
<select id="spiralist_workspace_attach_prompt" name="attach_prompt_slug" class="regular-text">