Export your knowledge base to various formats.
-
-
-
+
+
+
Export & Sync
+
+ Your local SQLite/OPFS storage is the canonical source of truth.
+ Use exports to share knowledge or create portable artifacts.
+
+
+
+
+ 1. Select Format
+
+ {formats.map((f) => (
+
+ ))}
+
+
+
+
+ 2. Define Scope
+
+ {(['all', 'selected', 'neighborhood', 'search'] as ExportScope[]).map((s) => (
+
+ ))}
+
+
+
+
+
+
+ {stats.entities}
+ Entities
+
+
+ {stats.claims}
+ Claims
+
+
+ {stats.links}
+ Links
+
+
+
+
+
+
+ {exportStatus === 'completed' && (
+
+ Export complete! Artifacts available in Lab/Downloads.
+
+ )}
+ {exportStatus === 'failed' && (
+
+ {error || 'Export failed. Check logs for details.'}
+
+ )}
+
);
diff --git a/src/styles/components.css b/src/styles/components.css
index 7338659..3be986b 100644
--- a/src/styles/components.css
+++ b/src/styles/components.css
@@ -655,3 +655,47 @@ input:focus, select:focus {
border-color: var(--border-focus);
box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.1);
}
+
+/* Job Metrics Overlay */
+.job-metrics-panel {
+ position: fixed;
+ bottom: var(--space-4);
+ right: var(--space-4);
+ background: var(--bg-surface);
+ color: var(--text-primary);
+ padding: var(--space-4);
+ border-radius: var(--radius-md);
+ box-shadow: var(--shadow-md);
+ border: 1px solid var(--border-default);
+ font-size: 11px;
+ z-index: 9999;
+ pointer-events: none;
+ font-family: var(--font-mono);
+ min-width: 200px;
+}
+
+.job-metrics-panel h4 {
+ margin: 0 0 var(--space-2) 0;
+ border-bottom: 1px solid var(--border-default);
+ padding-bottom: var(--space-1);
+ font-size: 10px;
+ text-transform: uppercase;
+ color: var(--text-muted);
+ letter-spacing: 0.05em;
+}
+
+.metrics-grid {
+ display: grid;
+ grid-template-columns: 1fr auto;
+ gap: var(--space-1) var(--space-4);
+}
+
+.metric-label {
+ color: var(--text-secondary);
+}
+
+.metric-value {
+ font-weight: 700;
+ color: var(--text-primary);
+ text-align: right;
+}
diff --git a/src/styles/features.css b/src/styles/features.css
index b94b86c..baa0a51 100644
--- a/src/styles/features.css
+++ b/src/styles/features.css
@@ -13,7 +13,7 @@
}
/* Feature specific containers */
-.editor-container, .chat-view {
+.editor-container, .chat-view, .export-view, .ai-harness-view {
background: var(--bg-surface);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-sm);
@@ -23,11 +23,283 @@
}
@media (min-width: 768px) {
- .editor-container, .chat-view {
+ .editor-container, .chat-view, .export-view, .ai-harness-view {
padding: var(--space-8);
}
}
+/* Export View Styles */
+.export-header {
+ margin-bottom: var(--space-8);
+}
+
+.export-intro {
+ color: var(--text-secondary);
+ font-size: 15px;
+ max-width: 600px;
+ margin-top: var(--space-2);
+}
+
+.export-section {
+ margin-bottom: var(--space-8);
+}
+
+.export-section h3 {
+ font-size: 14px;
+ text-transform: uppercase;
+ color: var(--text-muted);
+ letter-spacing: 0.05em;
+ margin-bottom: var(--space-4);
+}
+
+.format-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
+ gap: var(--space-4);
+}
+
+.format-card {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ text-align: left;
+ padding: var(--space-4);
+ background: var(--bg-surface);
+ border: 2px solid var(--border-default);
+ border-radius: var(--radius-md);
+ transition: all var(--motion-fast);
+ cursor: pointer;
+ width: 100%;
+}
+
+.format-card:hover {
+ border-color: var(--text-muted);
+}
+
+.format-card.selected {
+ border-color: var(--interactive-primary);
+ background: var(--bg-active);
+}
+
+.format-label {
+ font-weight: 700;
+ font-size: 16px;
+ color: var(--text-primary);
+ margin-bottom: var(--space-1);
+}
+
+.format-desc {
+ font-size: 13px;
+ color: var(--text-secondary);
+ line-height: 1.4;
+}
+
+.scope-selector {
+ display: flex;
+ gap: var(--space-2);
+ flex-wrap: wrap;
+}
+
+.export-footer {
+ margin-top: var(--space-10);
+ padding-top: var(--space-8);
+ border-top: 1px solid var(--border-default);
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-6);
+}
+
+.export-stats {
+ display: flex;
+ gap: var(--space-8);
+}
+
+.stat-item {
+ display: flex;
+ flex-direction: column;
+}
+
+.stat-value {
+ font-size: 24px;
+ font-weight: 700;
+ color: var(--text-primary);
+ line-height: 1;
+}
+
+.stat-label {
+ font-size: 12px;
+ text-transform: uppercase;
+ color: var(--text-muted);
+ font-weight: 600;
+ margin-top: var(--space-1);
+}
+
+.export-actions {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-4);
+ align-items: flex-start;
+}
+
+.export-button {
+ min-width: 200px;
+}
+
+.export-button.loading {
+ cursor: wait;
+ opacity: 0.8;
+}
+
+/* AI Harness View Styles */
+.ai-harness-header {
+ margin-bottom: var(--space-6);
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ flex-wrap: wrap;
+ gap: var(--space-4);
+}
+
+.header-main {
+ display: flex;
+ align-items: center;
+}
+
+.model-status-banner {
+ display: flex;
+ align-items: center;
+ gap: var(--space-2);
+ padding: var(--space-2) var(--space-4);
+ background: var(--bg-base);
+ border-radius: var(--radius-full);
+ border: 1px solid var(--border-default);
+}
+
+.status-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+}
+
+.status-dot.warning {
+ background: var(--status-warning);
+}
+
+.status-dot.success {
+ background: var(--status-success);
+}
+
+.status-text {
+ font-size: 12px;
+ font-weight: 600;
+ color: var(--text-secondary);
+}
+
+.harness-layout {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-4);
+ height: 600px;
+}
+
+.harness-tabs {
+ display: flex;
+ gap: var(--space-1);
+ border-bottom: 1px solid var(--border-default);
+}
+
+.harness-tabs button {
+ background: transparent;
+ border: none;
+ border-bottom: 2px solid transparent;
+ border-radius: 0;
+ padding: var(--space-2) var(--space-4);
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--text-muted);
+ min-height: auto;
+}
+
+.harness-tabs button:hover {
+ color: var(--text-secondary);
+}
+
+.harness-tabs button.active {
+ color: var(--interactive-primary);
+ border-bottom-color: var(--interactive-primary);
+}
+
+.harness-content {
+ flex: 1;
+ background: var(--bg-base);
+ border-radius: var(--radius-md);
+ border: 1px solid var(--border-default);
+ overflow: hidden;
+}
+
+.panel {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+}
+
+.panel-header {
+ padding: var(--space-3) var(--space-4);
+ border-bottom: 1px solid var(--border-default);
+ background: var(--bg-surface);
+}
+
+.panel-header h3 {
+ font-size: 12px;
+ text-transform: uppercase;
+ color: var(--text-muted);
+ letter-spacing: 0.05em;
+}
+
+.prompt-editor {
+ flex: 1;
+ padding: var(--space-4);
+ font-family: var(--font-mono);
+ font-size: 14px;
+ border: none;
+ resize: none;
+ background: transparent;
+ width: 100%;
+}
+
+.panel-footer {
+ padding: var(--space-4);
+ background: var(--bg-surface);
+ border-top: 1px solid var(--border-default);
+ display: flex;
+ justify-content: flex-end;
+}
+
+.empty-panel-state {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--text-muted);
+ font-style: italic;
+ font-size: 14px;
+}
+
+.log-entries {
+ flex: 1;
+ padding: var(--space-4);
+ font-family: var(--font-mono);
+ font-size: 12px;
+ overflow-y: auto;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-2);
+}
+
+.log-entry.info { color: var(--text-secondary); }
+.log-entry.warning { color: var(--status-warning); }
+.log-entry.error { color: var(--status-danger); }
+
.toolbar {
display: flex;
gap: var(--space-2);