438 lines
27 KiB
HTML
438 lines
27 KiB
HTML
<div id="step-panel-5" class="step-pane">
|
|
<div class="step-panel-header">
|
|
<div class="step-panel-eyebrow">
|
|
<div class="step-panel-eyebrow-line"></div>
|
|
<span data-step-counter>Step 5 of 5</span>
|
|
</div>
|
|
<h1 class="step-panel-title" data-i18n="wizard.step5.title">Mapping and execution</h1>
|
|
<p class="step-panel-subtitle" data-i18n="wizard.step5.subtitle">Define how MCP tool arguments map to upstream request fields, and how the upstream response maps back to MCP output. Then set execution parameters — auth is configured per-upstream in step 2.</p>
|
|
</div>
|
|
|
|
<div class="section-divider" style="margin-bottom: 16px;">
|
|
<span class="section-divider-label" data-i18n="wizard.step5.input_request">Input → Request</span>
|
|
<div class="section-divider-line"></div>
|
|
</div>
|
|
|
|
<div class="config-card" style="margin-bottom: 20px;">
|
|
<div class="config-card-body" style="gap: 0; padding: 0;">
|
|
<div class="code-block" style="border-radius: 0; border: none;">
|
|
<div class="code-toolbar">
|
|
<div class="code-dots"><span></span><span></span><span></span></div>
|
|
<span class="code-toolbar-label">yaml / input-mapping</span>
|
|
</div>
|
|
<textarea id="tool-input-mapping" class="form-textarea code-textarea" rows="12">first_name: "$.input.first_name"
|
|
last_name: "$.input.last_name"
|
|
email: "$.input.email"
|
|
company: "$.input.company"
|
|
phone: "$.input.phone"
|
|
source: "$.input.source"</textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section-divider" style="margin-bottom: 16px;">
|
|
<span class="section-divider-label" data-i18n="wizard.step5.output_response">Response → Output</span>
|
|
<div class="section-divider-line"></div>
|
|
</div>
|
|
|
|
<div class="config-card" style="margin-bottom: 20px;">
|
|
<div class="config-card-body" style="gap: 0; padding: 0;">
|
|
<div class="code-block" style="border-radius: 0; border: none;">
|
|
<div class="code-toolbar">
|
|
<div class="code-dots"><span></span><span></span><span></span></div>
|
|
<span class="code-toolbar-label">yaml / output-mapping</span>
|
|
</div>
|
|
<textarea id="tool-output-mapping" class="form-textarea code-textarea" rows="10">lead_id: "$.response.data.id"
|
|
status: "$.response.data.status"
|
|
created_at: "$.response.data.created_at"
|
|
owner_id: "$.response.data.owner.id"</textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section-divider" style="margin-bottom: 16px;">
|
|
<span class="section-divider-label" data-i18n="wizard.step5.execution">Execution</span>
|
|
<div class="section-divider-line"></div>
|
|
</div>
|
|
|
|
<div class="config-card" style="margin-bottom: 20px;">
|
|
<div class="config-card-header">
|
|
<div class="config-card-header-icon">
|
|
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
|
<circle cx="8" cy="8" r="6"/>
|
|
<path d="M8 5v3l2 2"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<div class="config-card-title" data-i18n="wizard.step5.exec_title">Execution config</div>
|
|
<div class="config-card-subtitle" data-i18n="wizard.step5.exec_subtitle">Timeouts, retry policy and auth profile reference</div>
|
|
</div>
|
|
<span class="config-card-optional" data-i18n="wizard.optional">Optional</span>
|
|
</div>
|
|
<div class="config-card-body" style="gap: 0; padding: 0;">
|
|
<div class="code-block" style="border-radius: 0; border: none;">
|
|
<div class="code-toolbar">
|
|
<div class="code-dots"><span></span><span></span><span></span></div>
|
|
<span class="code-toolbar-label">yaml / exec-config</span>
|
|
</div>
|
|
<textarea id="tool-exec-config" class="form-textarea code-textarea" rows="10">timeout_ms: 10000
|
|
retry:
|
|
max_attempts: 3
|
|
backoff_ms: 500
|
|
auth:
|
|
profile: acme_bearer
|
|
tls:
|
|
verify: true</textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="wizard-streaming-config-card" class="config-card" style="margin-bottom: 20px;">
|
|
<div class="config-card-header">
|
|
<div class="config-card-header-icon">
|
|
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M3 4h10M3 8h10M3 12h6"/>
|
|
<circle cx="12" cy="12" r="1.5"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<div class="config-card-title" data-i18n="wizard.streaming.title">Streaming execution</div>
|
|
<div class="config-card-subtitle" data-i18n="wizard.streaming.subtitle">Bounded stream, session and async job settings for MCP tool families.</div>
|
|
</div>
|
|
</div>
|
|
<div class="config-card-body" style="gap: 16px;">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.execution_mode">Execution mode</label>
|
|
<select id="streaming-mode" class="form-select">
|
|
<option value="unary">Unary</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.transport_behavior">Transport behavior</label>
|
|
<select id="streaming-transport-behavior" class="form-select">
|
|
<option value="request_response">Request / response</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.aggregation_mode">Aggregation mode</label>
|
|
<select id="streaming-aggregation-mode" class="form-select">
|
|
<option value="raw_items" data-i18n="wizard.streaming.aggregation.raw_items">Raw items</option>
|
|
<option value="summary_only" data-i18n="wizard.streaming.aggregation.summary_only">Summary only</option>
|
|
<option value="summary_plus_samples" data-i18n="wizard.streaming.aggregation.summary_plus_samples">Summary + samples</option>
|
|
<option value="stats" data-i18n="wizard.streaming.aggregation.stats">Stats</option>
|
|
<option value="latest_state" data-i18n="wizard.streaming.aggregation.latest_state">Latest state</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="streaming-mode-help" class="form-hint" data-i18n="wizard.streaming.help.unary">Unary keeps the existing request-response model. Other modes create bounded stream-aware MCP tools.</div>
|
|
|
|
<div id="streaming-limits-grid" class="form-row">
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.window_duration">Window duration (ms)</label>
|
|
<input id="streaming-window-duration-ms" class="form-input" type="number" min="1" step="1" placeholder="5000">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.poll_interval">Poll interval (ms)</label>
|
|
<input id="streaming-poll-interval-ms" class="form-input" type="number" min="1" step="1" placeholder="2000">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.upstream_timeout">Upstream timeout (ms)</label>
|
|
<input id="streaming-upstream-timeout-ms" class="form-input" type="number" min="1" step="1" placeholder="10000">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.idle_timeout">Idle timeout (ms)</label>
|
|
<input id="streaming-idle-timeout-ms" class="form-input" type="number" min="1" step="1" placeholder="30000">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.session_lifetime">Session lifetime (ms)</label>
|
|
<input id="streaming-session-lifetime-ms" class="form-input" type="number" min="1" step="1" placeholder="300000">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.max_items">Max items</label>
|
|
<input id="streaming-max-items" class="form-input" type="number" min="1" step="1" placeholder="100">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.max_bytes">Max bytes</label>
|
|
<input id="streaming-max-bytes" class="form-input" type="number" min="1" step="1" placeholder="65536">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.max_field_length">Max field length</label>
|
|
<input id="streaming-max-field-length" class="form-input" type="number" min="1" step="1" placeholder="512">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.sampling_rate">Sampling rate</label>
|
|
<input id="streaming-sampling-rate" class="form-input" type="number" min="0" max="1" step="0.1" placeholder="1.0">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.items_path">Items path</label>
|
|
<input id="streaming-items-path" class="form-input input-mono" type="text" placeholder="$.items">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.summary_path">Summary path</label>
|
|
<input id="streaming-summary-path" class="form-input input-mono" type="text" placeholder="$.summary">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.done_path">Done path</label>
|
|
<input id="streaming-done-path" class="form-input input-mono" type="text" placeholder="$.done">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.cursor_path">Cursor path</label>
|
|
<input id="streaming-cursor-path" class="form-input input-mono" type="text" placeholder="$.cursor">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.status_path">Status path</label>
|
|
<input id="streaming-status-path" class="form-input input-mono" type="text" placeholder="$.status">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.redacted_paths">Redacted paths</label>
|
|
<textarea id="streaming-redacted-paths" class="form-textarea code-textarea" rows="4" spellcheck="false" placeholder="$.items[*].token $.summary.secret"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<label class="checkbox-pill"><input id="streaming-truncate-item-fields" type="checkbox"> <span data-i18n="wizard.streaming.truncate_item_fields">Truncate item fields</span></label>
|
|
<label class="checkbox-pill"><input id="streaming-drop-duplicates" type="checkbox"> <span data-i18n="wizard.streaming.drop_duplicates">Drop duplicates</span></label>
|
|
</div>
|
|
|
|
<div id="streaming-tool-family-block" style="display:none;">
|
|
<div class="section-divider" style="margin: 8px 0 16px;">
|
|
<span class="section-divider-label" data-i18n="wizard.streaming.tool_family">Tool family</span>
|
|
<div class="section-divider-line"></div>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.start_tool_name">Start tool name</label>
|
|
<input id="streaming-start-tool-name" class="form-input input-mono" type="text" placeholder="logs_follow_start">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.poll_tool_name">Poll tool name</label>
|
|
<input id="streaming-poll-tool-name" class="form-input input-mono" type="text" placeholder="logs_follow_poll">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.stop_tool_name">Stop tool name</label>
|
|
<input id="streaming-stop-tool-name" class="form-input input-mono" type="text" placeholder="logs_follow_stop">
|
|
</div>
|
|
</div>
|
|
<div class="form-row" id="streaming-async-tool-family-row" style="display:none;">
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.status_tool_name">Status tool name</label>
|
|
<input id="streaming-status-tool-name" class="form-input input-mono" type="text" placeholder="deploy_status">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.result_tool_name">Result tool name</label>
|
|
<input id="streaming-result-tool-name" class="form-input input-mono" type="text" placeholder="deploy_result">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.streaming.cancel_tool_name">Cancel tool name</label>
|
|
<input id="streaming-cancel-tool-name" class="form-input input-mono" type="text" placeholder="deploy_cancel">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section-divider" style="margin-bottom: 16px;">
|
|
<span class="section-divider-label" data-i18n="wizard.step5.live_title">Live validation and publishing</span>
|
|
<div class="section-divider-line"></div>
|
|
</div>
|
|
|
|
<div id="wizard-live-status" class="info-callout" style="margin-bottom: 20px; display:none;">
|
|
<svg class="info-callout-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
|
<circle cx="8" cy="8" r="7"/>
|
|
<path d="M8 11V8M8 5v-.5"/>
|
|
</svg>
|
|
<div class="info-callout-body">
|
|
<div class="info-callout-title" id="wizard-live-status-title" data-i18n="wizard.step5.draft_actions">Draft actions</div>
|
|
<div class="info-callout-text" id="wizard-live-status-text"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="info-callout info-callout-subtle" style="margin-bottom: 20px;">
|
|
<svg class="info-callout-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
|
<circle cx="8" cy="8" r="7"/>
|
|
<path d="M8 11V8M8 5v-.5"/>
|
|
</svg>
|
|
<div class="info-callout-body">
|
|
<div class="info-callout-title" data-i18n="wizard.step5.live_save_title">Live actions save the draft first</div>
|
|
<div class="info-callout-text" data-i18n="wizard.step5.live_save_body">Sample uploads, test runs, YAML actions, publish and gRPC descriptor discovery all persist the current draft before calling the backend.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="config-card" style="margin-bottom: 20px;">
|
|
<div class="config-card-header">
|
|
<div class="config-card-header-icon">
|
|
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
|
<rect x="2" y="3" width="12" height="10" rx="1.5"/>
|
|
<path d="M5 7h6M5 10h6"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<div class="config-card-title" data-i18n="wizard.step5.samples_title">Samples and draft generation</div>
|
|
<div class="config-card-subtitle" data-i18n="wizard.step5.samples_subtitle">Persist input/output samples, then generate schemas and mappings from real payloads.</div>
|
|
</div>
|
|
</div>
|
|
<div class="config-card-body" style="gap: 16px;">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.step5.input_sample">Input sample</label>
|
|
<textarea id="wizard-input-sample" class="form-textarea code-textarea" rows="9" spellcheck="false">{
|
|
"first_name": "Ada",
|
|
"last_name": "Lovelace",
|
|
"email": "ada@example.com"
|
|
}</textarea>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.step5.output_sample">Output sample</label>
|
|
<textarea id="wizard-output-sample" class="form-textarea code-textarea" rows="9" spellcheck="false">{
|
|
"id": "lead_123",
|
|
"status": "created"
|
|
}</textarea>
|
|
</div>
|
|
</div>
|
|
<div style="display:flex; gap: 8px; flex-wrap: wrap;">
|
|
<button id="wizard-upload-input-sample" class="btn-primary-sm" type="button" data-i18n="wizard.step5.save_input_sample">Save input sample</button>
|
|
<button id="wizard-upload-output-sample" class="btn-ghost-sm" type="button" data-i18n="wizard.step5.save_output_sample">Save output sample</button>
|
|
<button id="wizard-generate-draft" class="btn-ghost-sm" type="button" data-i18n="wizard.step5.generate_draft">Generate draft from samples</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="config-card" style="margin-bottom: 20px;">
|
|
<div class="config-card-header">
|
|
<div class="config-card-header-icon">
|
|
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M2 8h12M10 4l4 4-4 4"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<div class="config-card-title" data-i18n="wizard.step5.test_title">Test run</div>
|
|
<div class="config-card-subtitle" data-i18n="wizard.step5.test_subtitle">Run the current draft against the upstream before publishing it.</div>
|
|
</div>
|
|
</div>
|
|
<div class="config-card-body" style="gap: 16px;">
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.step5.test_input_payload">Test input payload</label>
|
|
<textarea id="wizard-test-input" class="form-textarea code-textarea" rows="8" spellcheck="false">{
|
|
"first_name": "Ada",
|
|
"last_name": "Lovelace",
|
|
"email": "ada@example.com"
|
|
}</textarea>
|
|
</div>
|
|
<div style="display:flex; gap: 8px; flex-wrap: wrap;">
|
|
<button id="wizard-run-test" class="btn-primary-sm" type="button" data-i18n="wizard.step5.run_test">Run test</button>
|
|
<button id="wizard-copy-test-response" class="btn-ghost-sm" type="button" data-i18n="wizard.step5.use_response_output">Use response as output sample</button>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.step5.request_preview">Request preview</label>
|
|
<textarea id="wizard-test-request-preview" class="form-textarea code-textarea" rows="8" spellcheck="false" readonly></textarea>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.step5.response_preview">Response preview</label>
|
|
<textarea id="wizard-test-response-preview" class="form-textarea code-textarea" rows="8" spellcheck="false" readonly></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.step5.errors">Errors</label>
|
|
<textarea id="wizard-test-errors" class="form-textarea code-textarea" rows="4" spellcheck="false" readonly></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="wizard-grpc-live-tools" class="config-card" style="margin-bottom: 20px; display:none;">
|
|
<div class="config-card-header">
|
|
<div class="config-card-header-icon">
|
|
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M9 2H4a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V6z"/>
|
|
<path d="M9 2v4h4"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<div class="config-card-title" data-i18n="wizard.step5.grpc_descriptor_title">gRPC descriptor set</div>
|
|
<div class="config-card-subtitle" data-i18n="wizard.step5.grpc_descriptor_subtitle">Upload a compiled descriptor set and discover unary methods from the saved draft.</div>
|
|
</div>
|
|
</div>
|
|
<div class="config-card-body" style="gap: 16px;">
|
|
<div style="display:flex; gap: 8px; align-items:center; flex-wrap: wrap;">
|
|
<input id="wizard-descriptor-set-input" type="file" accept=".bin,.pb,.desc,.protoset,application/octet-stream" style="display:none">
|
|
<button id="wizard-select-descriptor-set" class="btn-ghost-sm" type="button" data-i18n="wizard.step5.choose_descriptor">Choose descriptor set</button>
|
|
<button id="wizard-upload-descriptor-set" class="btn-primary-sm" type="button" data-i18n="wizard.step5.upload_discover">Upload and discover services</button>
|
|
<span id="wizard-descriptor-set-name" style="color: var(--text-muted); font-size: 12px;" data-i18n="wizard.step5.no_descriptor">No descriptor set selected</span>
|
|
</div>
|
|
<div id="wizard-descriptor-services-summary" class="form-hint"></div>
|
|
<div id="wizard-descriptor-services-list" style="display:grid; gap: 10px;"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="config-card" style="margin-bottom: 20px;">
|
|
<div class="config-card-header">
|
|
<div class="config-card-header-icon">
|
|
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M8 2v12M3 7l5-5 5 5"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<div class="config-card-title" data-i18n="wizard.step5.yaml_title">YAML import and export</div>
|
|
<div class="config-card-subtitle" data-i18n="wizard.step5.yaml_subtitle">Move operation drafts between environments without leaving the wizard.</div>
|
|
</div>
|
|
</div>
|
|
<div class="config-card-body" style="gap: 16px;">
|
|
<div style="display:flex; gap: 8px; flex-wrap: wrap;">
|
|
<button id="wizard-export-yaml" class="btn-ghost-sm" type="button" data-i18n="wizard.step5.export_yaml">Export YAML</button>
|
|
<button id="wizard-import-yaml-file-trigger" class="btn-ghost-sm" type="button" data-i18n="wizard.step5.load_yaml_file">Load YAML file</button>
|
|
<button id="wizard-import-yaml" class="btn-primary-sm" type="button" data-i18n="wizard.step5.import_yaml">Import YAML</button>
|
|
<input id="wizard-import-yaml-file" type="file" accept=".yaml,.yml,text/yaml" style="display:none">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label" data-i18n="wizard.step5.yaml_document">YAML document</label>
|
|
<textarea id="wizard-import-yaml-text" class="form-textarea code-textarea" rows="10" spellcheck="false" data-i18n-ph="wizard.step5.yaml_placeholder" placeholder="Paste exported YAML here to create or upsert an operation."></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="config-card" style="margin-bottom: 20px;">
|
|
<div class="config-card-header">
|
|
<div class="config-card-header-icon">
|
|
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M3 8l3 3 7-7"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<div class="config-card-title" data-i18n="wizard.step5.publish_title">Publish</div>
|
|
<div class="config-card-subtitle" data-i18n="wizard.step5.publish_subtitle">Save the current draft and expose it to published agents.</div>
|
|
</div>
|
|
</div>
|
|
<div class="config-card-body" style="gap: 12px;">
|
|
<div class="form-hint" data-i18n="wizard.step5.publish_hint">Publishing uses the current draft version from this wizard session.</div>
|
|
<div style="display:flex; gap: 8px; flex-wrap: wrap;">
|
|
<button id="wizard-publish-operation" class="btn-primary-sm" type="button" data-i18n="wizard.step5.publish_action">Publish operation</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="info-callout" style="margin-bottom: 24px;">
|
|
<svg class="info-callout-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
|
<circle cx="8" cy="8" r="7"/>
|
|
<path d="M8 11V8M8 5v-.5"/>
|
|
</svg>
|
|
<div class="info-callout-body">
|
|
<div class="info-callout-title" data-i18n="wizard.step5.editable_title">Operation stays editable in this wizard</div>
|
|
<div class="info-callout-text" data-i18n="wizard.step5.editable_body">Saving creates or updates the current draft in place. Use the live actions above to upload samples, test the draft, export or import YAML, and publish when the upstream contract is ready.</div>
|
|
</div>
|
|
</div>
|
|
</div><!-- /step-pane-5 -->
|