feat: complete Epic 1 production foundation
This commit is contained in:
@@ -215,6 +215,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="agent-card-date" style="margin-top:8px;" x-text="endpointHelpText(agent)"></div>
|
||||
<div class="agent-card-date" style="margin-top:6px;" x-text="agentRevisionText(agent)"></div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="agent-card-footer">
|
||||
@@ -224,15 +225,15 @@
|
||||
<svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M11 2l3 3-8 8H3v-3l8-8z"/></svg>
|
||||
<span data-i18n="agents.action.edit">Edit</span>
|
||||
</button>
|
||||
<button class="agent-action-btn" @click.stop="applyLifecycle(agent, lifecycleAction(agent).key)">
|
||||
<button class="agent-action-btn" :disabled="lifecycleDisabled(agent)" @click.stop="applyLifecycle(agent, lifecycleAction(agent).key)">
|
||||
<svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 3.5v9l8-4.5-8-4.5z"/></svg>
|
||||
<span x-text="lifecycleAction(agent).label"></span>
|
||||
</button>
|
||||
<button class="agent-action-btn" x-show="agent.raw_status !== 'archived'" @click.stop="applyLifecycle(agent, 'archive')">
|
||||
<button class="agent-action-btn" x-show="agent.raw_status !== 'archived'" :disabled="lifecycleDisabled(agent)" @click.stop="applyLifecycle(agent, 'archive')">
|
||||
<svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 4.5h11v2l-1 6.5h-8l-1-6.5v-2z"/><path d="M5 4.5v-1A1.5 1.5 0 016.5 2h3A1.5 1.5 0 0111 3.5v1"/></svg>
|
||||
<span data-i18n="agents.action.archive">Archive</span>
|
||||
</button>
|
||||
<button class="agent-action-btn danger" @click.stop="deleteAgent(agent.id)">
|
||||
<button class="agent-action-btn danger" :disabled="lifecycleDisabled(agent)" @click.stop="deleteAgent(agent.id)">
|
||||
<svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M2 4h12M5 4V3a1 1 0 011-1h4a1 1 0 011 1v1M10 8v4M6 8v4"/><path d="M3 4l1 9a1 1 0 001 1h6a1 1 0 001-1l1-9"/></svg>
|
||||
<span data-i18n="agents.action.delete">Delete</span>
|
||||
</button>
|
||||
@@ -295,6 +296,7 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" data-i18n="agents.drawer.status">Status</label>
|
||||
<div class="form-hint" x-show="drawerMode === 'edit'" x-text="drawerRevisionText()"></div>
|
||||
<div class="agent-status-toggle">
|
||||
<button class="agent-status-opt" :class="{ active: form.status === 'published' }" @click="form.status = 'published'">
|
||||
<span class="status-dot" style="background: var(--success, #3fb950)"></span> <span data-i18n="agents.lifecycle.published">Published</span>
|
||||
@@ -474,7 +476,7 @@
|
||||
<div class="drawer-footer">
|
||||
<button class="btn-ghost-sm" style="padding: 8px 16px; font-size: 13px;" @click="closeDrawer()" data-i18n="agents.drawer.cancel">Cancel</button>
|
||||
<button class="btn-primary-sm" style="padding: 8px 20px; font-size: 13px;"
|
||||
:disabled="!form.display_name.trim() || !form.slug.trim() || !catalogConfigValid"
|
||||
:disabled="saving || !form.display_name.trim() || !form.slug.trim() || !catalogConfigValid"
|
||||
@click="saveAgent()"
|
||||
x-text="drawerMode === 'create' ? tKey('agents.drawer.create') : tKey('agents.drawer.save')">
|
||||
Create agent
|
||||
|
||||
@@ -251,10 +251,10 @@
|
||||
|
||||
<!-- ══ Create Key Modal ══ -->
|
||||
<div class="modal-overlay" id="modal-create">
|
||||
<div class="modal">
|
||||
<div class="modal" role="dialog" aria-modal="true" aria-labelledby="modal-create-title">
|
||||
<div class="modal-header">
|
||||
<span class="modal-title" id="modal-create-title" data-i18n="apikeys.modal.title">Create agent key</span>
|
||||
<button class="modal-close" id="modal-close-btn" type="button">
|
||||
<button class="modal-close" id="modal-close-btn" type="button" aria-label="Close">
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round">
|
||||
<line x1="1" y1="1" x2="11" y2="11"/><line x1="11" y1="1" x2="1" y2="11"/>
|
||||
</svg>
|
||||
@@ -277,6 +277,15 @@
|
||||
<div style="display:flex;flex-direction:column;gap:8px;margin-top:2px;" id="scope-checkboxes">
|
||||
</div>
|
||||
</div>
|
||||
<div class="callout warning" id="ambiguous-create-warning" data-testid="ambiguous-create-warning" hidden>
|
||||
<div>
|
||||
<strong data-i18n="apikeys.ambiguous.title">Creation result is uncertain.</strong>
|
||||
<span data-i18n="apikeys.ambiguous.body">Key metadata was refreshed. Review the list before deliberately creating another key.</span>
|
||||
<div style="margin-top:10px;">
|
||||
<button class="btn-secondary" id="ambiguous-create-retry-btn" type="button" data-i18n="apikeys.ambiguous.retry">Refresh metadata and allow another attempt</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body" id="modal-reveal-body" hidden>
|
||||
<div class="callout warning" style="margin-bottom:16px;">
|
||||
@@ -294,6 +303,13 @@
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="callout warning" id="onboarding-clipboard-warning" data-testid="onboarding-clipboard-warning" hidden style="margin-top:12px;">
|
||||
<div data-i18n="apikeys.modal.clipboard_warning">Your operating system clipboard is outside Crank control. Clear it after saving the key.</div>
|
||||
</div>
|
||||
<div id="onboarding-connection-config" data-testid="onboarding-connection-config" hidden style="margin-top:14px;">
|
||||
<div class="field-label" data-i18n="apikeys.modal.connection_title">MCP connection configuration</div>
|
||||
<div id="onboarding-connection-clients"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer" id="modal-footer-create">
|
||||
<button class="btn-secondary" id="modal-cancel-btn" type="button" data-i18n="apikeys.modal.cancel">Cancel</button>
|
||||
@@ -305,6 +321,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="callout warning" id="onboarding-key-lost" data-testid="onboarding-key-lost" hidden style="position:fixed;right:22px;bottom:82px;z-index:760;max-width:420px;">
|
||||
<div data-i18n="apikeys.onboarding.key_lost">The key cannot be shown again. Create a new key and revoke the old one if its value was not saved.</div>
|
||||
</div>
|
||||
|
||||
<!-- Template: scope checkbox row -->
|
||||
<template id="tmpl-scope-checkbox">
|
||||
<label class="scope-checkbox-label">
|
||||
|
||||
@@ -30,17 +30,22 @@
|
||||
</div>
|
||||
|
||||
<form id="login-form" novalidate>
|
||||
<div class="field">
|
||||
<div class="field" id="login-email-field">
|
||||
<label class="field-label" for="email" data-i18n="login.email_label">Email address</label>
|
||||
<input class="field-input" type="email" id="email" data-i18n-ph="login.email_placeholder" placeholder="you@acme.com" autocomplete="email" autofocus>
|
||||
</div>
|
||||
|
||||
<div class="field" id="login-bootstrap-token-field" hidden>
|
||||
<label class="field-label" for="bootstrap-token" data-i18n="login.bootstrap.token_label">Bootstrap token</label>
|
||||
<input class="field-input" type="password" id="bootstrap-token" data-i18n-ph="login.bootstrap.token_placeholder" placeholder="Paste one-time bootstrap token" autocomplete="one-time-code"> <!-- community-scope: allow=one-time-token -->
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="field-label" for="password" data-i18n="login.password">Password</label>
|
||||
<input class="field-input" type="password" id="password" placeholder="••••••••" autocomplete="current-password">
|
||||
</div>
|
||||
|
||||
<button class="btn-signin" type="submit" data-i18n="login.submit">Sign in</button>
|
||||
<button class="btn-signin" id="login-submit" type="submit" data-i18n="login.submit">Sign in</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -108,6 +108,31 @@
|
||||
|
||||
<div class="toolbar-sep"></div>
|
||||
|
||||
<select class="time-range-select" id="status-filter" data-i18n-title="logs.status_filter" title="Status">
|
||||
<option value="all" selected data-i18n="logs.status.all">All statuses</option>
|
||||
<option value="ok" data-i18n="logs.status.ok">Success</option>
|
||||
<option value="error" data-i18n="logs.status.error">Error</option>
|
||||
</select>
|
||||
|
||||
<select class="time-range-select" id="outcome-filter" data-i18n-title="logs.outcome_filter" title="Outcome">
|
||||
<option value="all" selected data-i18n="logs.outcome.all">All outcomes</option>
|
||||
<option value="success" data-i18n="usage.outcome.success">Success</option>
|
||||
<option value="upstream" data-i18n="usage.outcome.upstream">Upstream</option>
|
||||
<option value="client" data-i18n="usage.outcome.client">Client</option>
|
||||
<option value="schema" data-i18n="usage.outcome.schema">Schema</option>
|
||||
<option value="crank" data-i18n="usage.outcome.crank">Crank</option>
|
||||
</select>
|
||||
|
||||
<div class="filter-bar-search log-id-filter">
|
||||
<input type="text" id="operation-filter" data-i18n-ph="logs.filter.operation" placeholder="Operation ID" autocomplete="off" spellcheck="false">
|
||||
</div>
|
||||
|
||||
<div class="filter-bar-search log-id-filter">
|
||||
<input type="text" id="agent-filter" data-i18n-ph="logs.filter.agent" placeholder="Agent ID" autocomplete="off" spellcheck="false">
|
||||
</div>
|
||||
|
||||
<div class="toolbar-sep"></div>
|
||||
|
||||
<button class="filter-chip active" data-level="all" id="chip-all" data-i18n="logs.level.all">All</button>
|
||||
<button class="filter-chip" data-level="info" id="chip-info">
|
||||
<span class="log-level info" style="padding:0 4px;font-size:10px;">INFO</span>
|
||||
@@ -128,10 +153,18 @@
|
||||
<svg width="12" height="12" viewBox="0 0 16 16" fill="currentColor"><path d="M1.705 8.005a.75.75 0 01.834.656 5.5 5.5 0 009.592 2.97l-1.204-1.204a.25.25 0 01.177-.427h3.646a.25.25 0 01.25.25v3.646a.25.25 0 01-.427.177l-1.38-1.38A7.001 7.001 0 011.05 8.84a.75.75 0 01.656-.834zM8 2.5a5.487 5.487 0 00-4.131 1.869l1.204 1.204A.25.25 0 014.896 6H1.25A.25.25 0 011 5.75V2.104a.25.25 0 01.427-.177l1.38 1.38A7.001 7.001 0 0114.95 7.16a.75.75 0 01-1.49.178A5.501 5.501 0 008 2.5z"/></svg>
|
||||
<span data-i18n="logs.refresh">Refresh</span>
|
||||
</button>
|
||||
<button class="refresh-btn" id="export-logs-btn" type="button">
|
||||
<span data-i18n="logs.export">Export CSV</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="log-list" id="log-list">
|
||||
</div>
|
||||
<div class="log-pagination">
|
||||
<button class="refresh-btn" id="load-more-logs-btn" type="button" hidden>
|
||||
<span data-i18n="logs.load_more">Load more</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -147,6 +147,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-card" style="margin-bottom:20px;">
|
||||
<div class="section-card-header">
|
||||
<div>
|
||||
<div class="section-card-title" data-i18n="usage.outcomes.title">Outcomes</div>
|
||||
<div class="section-card-subtitle" data-i18n="usage.outcomes.subtitle">Grouped by safe execution outcome.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-list usage-card-list" id="usage-outcome-list" style="display:grid;padding:16px 20px;"></div>
|
||||
</div>
|
||||
|
||||
<!-- Per-operation table -->
|
||||
<div class="section-card">
|
||||
<div class="section-card-header">
|
||||
|
||||
@@ -131,7 +131,7 @@ tls:
|
||||
<div class="section-divider-line"></div>
|
||||
</div>
|
||||
|
||||
<div id="wizard-live-status" class="info-callout" hidden style="margin-bottom: 20px;">
|
||||
<div id="wizard-live-status" class="info-callout" role="status" aria-live="polite" aria-atomic="true" hidden 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"/>
|
||||
@@ -284,6 +284,16 @@ tls:
|
||||
<button id="wizard-run-test" class="btn-primary-sm" type="button" data-i18n="wizard.step5.run_test">Запустить тест</button>
|
||||
<button id="wizard-copy-test-response" class="btn-ghost-sm" type="button" data-i18n="wizard.step5.use_response_output">Использовать ответ как выходной пример</button>
|
||||
</div>
|
||||
<div id="wizard-test-correlation" class="info-callout" role="status" aria-live="polite" hidden>
|
||||
<div class="info-callout-body">
|
||||
<div><span data-i18n="wizard.test.request_id">Request ID</span>: <code id="wizard-test-request-id"></code></div>
|
||||
<div><span data-i18n="wizard.test.trace_id">Trace ID</span>: <code id="wizard-test-trace-id"></code></div>
|
||||
<div style="display:flex; gap:8px; flex-wrap:wrap; margin-top:8px;">
|
||||
<button id="wizard-copy-request-id" class="btn-ghost-sm" type="button" data-i18n="wizard.test.copy_request_id">Copy Request ID</button>
|
||||
<button id="wizard-copy-trace-id" class="btn-ghost-sm" type="button" data-i18n="wizard.test.copy_trace_id">Copy Trace ID</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label class="form-label" data-i18n="wizard.step5.request_preview">Предпросмотр API-запроса</label>
|
||||
|
||||
Reference in New Issue
Block a user