feat(dirac): core formatters + webview-ui components

This commit is contained in:
fabiorafaelcoutada 2026-07-12 20:52:58 +01:00
parent 447540866b
commit f3a5e26e84
3 changed files with 930 additions and 0 deletions

View file

@ -0,0 +1,203 @@
fin/**
* TOON (Token-Optimized Object Notation) Formatter
* A token-efficient alternative to JSON for AI agent communication
* Converts arrays of uniform objects to a table-like format with headers and rows
*/
export interface TOONOptions {
maxArrayLength?: number;
minTokenSavings?: number;
preferTOON?: boolean;
}
export interface TOONResult {
format: 'toon' | 'json';
content: string;
originalTokenCount: number;
convertedTokenCount: number;
tokenSavings: number;
tokenSavingsPercent: number;
}
/**
* Determines if an array of objects is suitable for TOON conversion
*/
function isUniformObjectArray(data: any[]): boolean {
if (!Array.isArray(data) || data.length === 0) {
return false;
}
// Check if all items are objects
if (!data.every(item => typeof item === 'object' && item !== null && !Array.isArray(item))) {
return false;
}
// Get keys from the first object
const firstKeys = Object.keys(data[0]).sort();
// Check if all objects have the same keys
return data.every(obj => {
const objKeys = Object.keys(obj).sort();
return objKeys.length === firstKeys.length &&
objKeys.every((key, i) => key === firstKeys[i]);
});
}
/**
* Converts an array of uniform objects to TOON format
*/
function convertToTOON(data: any[]): string {
if (!isUniformObjectArray(data)) {
throw new Error('Data is not suitable for TOON conversion');
}
const headers = Object.keys(data[0]);
const rows = data.map(obj => headers.map(header => obj[header]));
// Create TOON format: headers followed by rows
let toonStr = '| ' + headers.join(' | ') + ' |\n';
toonStr += '|' + headers.map(() => ' --- ').join('|') + '|\n';
toonStr += rows.map(row => '| ' + row.join(' | ') + ' |').join('\n');
return toonStr;
}
/**
* Estimates token count for a string (approximate)
*/
function estimateTokenCount(str: string): number {
// Rough estimation: 1 token ≈ 4 characters, but punctuation and common words are fewer
return Math.ceil(str.length / 4);
}
/**
* Format data using TOON when beneficial for token savings
*/
export function formatDataTOON(data: any, options: TOONOptions = {}): TOONResult {
const {
maxArrayLength = 100,
minTokenSavings = 0.1, // Require at least 10% savings
preferTOON = false
} = options;
// Convert data to JSON first to get baseline
const jsonStr = JSON.stringify(data, null, 2);
const originalTokenCount = estimateTokenCount(jsonStr);
// Check if data is a suitable array for TOON conversion
if (Array.isArray(data) &&
data.length > 0 &&
data.length <= maxArrayLength &&
isUniformObjectArray(data)) {
try {
const toonStr = convertToTOON(data);
const convertedTokenCount = estimateTokenCount(toonStr);
const tokenSavings = originalTokenCount - convertedTokenCount;
const tokenSavingsPercent = originalTokenCount > 0 ? (tokenSavings / originalTokenCount) * 100 : 0;
// Use TOON if it saves tokens beyond the threshold OR if TOON is preferred
if (tokenSavingsPercent >= (minTokenSavings * 100) || preferTOON) {
return {
format: 'toon',
content: toonStr,
originalTokenCount,
convertedTokenCount,
tokenSavings,
tokenSavingsPercent
};
}
} catch (error) {
console.warn('TOON conversion failed, falling back to JSON:', error);
}
}
// Return JSON if TOON isn't beneficial or applicable
return {
format: 'json',
content: jsonStr,
originalTokenCount,
convertedTokenCount: originalTokenCount,
tokenSavings: 0,
tokenSavingsPercent: 0
};
}
/**
* Parse TOON formatted string back to array of objects
*/
export function parseTOON(toonStr: string): any[] {
const lines = toonStr.split('\n').filter(line => line.trim() !== '');
if (lines.length < 2) {
throw new Error('Invalid TOON format: insufficient lines');
}
// Find header and separator lines
let headerLineIndex = -1;
let separatorLineIndex = -1;
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.startsWith('|') && line.includes('|')) {
if (headerLineIndex === -1) {
headerLineIndex = i;
} else if (separatorLineIndex === -1 && line.includes('---')) {
separatorLineIndex = i;
break;
}
}
}
if (headerLineIndex === -1 || separatorLineIndex === -1) {
throw new Error('Invalid TOON format: missing header or separator line');
}
// Extract headers
const headerLine = lines[headerLineIndex];
const headers = headerLine
.split('|')
.map(h => h.trim())
.filter(h => h !== '');
// Process data rows
const dataRows = lines.slice(separatorLineIndex + 1).filter(line =>
line.trim().startsWith('|') && line.trim().endsWith('|')
);
const result: any[] = [];
for (const row of dataRows) {
const values = row
.split('|')
.map(v => v.trim())
.filter(v => v !== '');
if (values.length === headers.length) {
const obj: any = {};
for (let i = 0; i < headers.length; i++) {
// Try to parse as JSON if it looks like a complex value, otherwise use as string
let value = values[i];
try {
// Attempt to parse as JSON for numbers, booleans, etc.
if (value === 'true') value = true;
else if (value === 'false') value = false;
else if (value === 'null') value = null;
else if (/^-?\d+$/.test(value)) value = parseInt(value, 10);
else if (/^-?\d*\.\d+$/.test(value)) value = parseFloat(value);
} catch (e) {
// Keep as string if JSON parsing fails
}
obj[headers[i]] = value;
}
result.push(obj);
}
}
return result;
}
/**
* Benchmark TOON vs JSON token efficiency
*/
export function benchmarkTOON(data: any, options: TOONOptions = {}): TOONResult {
return formatDataTOON(data, options);
}

View file

@ -0,0 +1,376 @@
import React, { useState, useEffect, useRef } from 'react';
import { VSCodeButton, VSCodeTextField, VSCodeCheckbox } from '@vscode/webview-ui-toolkit/react';
interface Book {
id: string;
title: string;
author: string;
totalPages: number;
currentPage: number;
progress: number;
bookmarks: number[];
annotations: Annotation[];
format: 'pdf' | 'epub' | 'text';
}
interface Annotation {
id: string;
page: number;
text: string;
highlight: string;
timestamp: Date;
}
interface ImmersiveReaderProps {
book: Book;
onClose: () => void;
}
const ImmersiveReader: React.FC<ImmersiveReaderProps> = ({ book, onClose }) => {
const [currentPage, setCurrentPage] = useState(book.currentPage);
const [fontSize, setFontSize] = useState(16);
const [lineHeight, setLineHeight] = useState(1.5);
const [theme, setTheme] = useState<'light' | 'dark' | 'sepia'>('light');
const [showBookmarks, setShowBookmarks] = useState(true);
const [showAnnotations, setShowAnnotations] = useState(true);
const [searchQuery, setSearchQuery] = useState('');
const [searchResults, setSearchResults] = useState<{page: number, index: number}[]>([]);
const [currentSearchIndex, setCurrentSearchIndex] = useState(0);
const [newAnnotation, setNewAnnotation] = useState('');
const [isAddingAnnotation, setIsAddingAnnotation] = useState(false);
const [readingMode, setReadingMode] = useState<'continuous' | 'paged'>('continuous');
const contentRef = useRef<HTMLDivElement>(null);
// Calculate progress percentage
useEffect(() => {
const progress = (currentPage / book.totalPages) * 100;
// Update book progress in parent component or state
}, [currentPage, book.totalPages]);
// Handle search
useEffect(() => {
if (searchQuery.trim() === '') {
setSearchResults([]);
return;
}
// Mock search functionality - in real implementation this would search the book content
const results = [];
for (let i = 1; i <= book.totalPages; i++) {
// Simulate finding search term on random pages
if (Math.random() > 0.7) {
results.push({ page: i, index: Math.floor(Math.random() * 10) });
}
}
setSearchResults(results);
setCurrentSearchIndex(0);
}, [searchQuery]);
const handlePageChange = (direction: 'next' | 'prev') => {
if (direction === 'next' && currentPage < book.totalPages) {
setCurrentPage(currentPage + 1);
} else if (direction === 'prev' && currentPage > 1) {
setCurrentPage(currentPage - 1);
}
};
const handleGoToPage = (page: number) => {
if (page >= 1 && page <= book.totalPages) {
setCurrentPage(page);
}
};
const handleBookmarkToggle = (page: number) => {
// In real implementation, this would update book bookmarks
console.log(`Toggled bookmark for page ${page}`);
};
const handleAddAnnotation = () => {
if (newAnnotation.trim() !== '') {
// In real implementation, this would add annotation to book
const annotation: Annotation = {
id: `ann_${Date.now()}`,
page: currentPage,
text: newAnnotation,
highlight: 'selected_text_placeholder',
timestamp: new Date()
};
console.log('Added annotation:', annotation);
setNewAnnotation('');
setIsAddingAnnotation(false);
}
};
const handleSearchNavigation = (direction: 'next' | 'prev') => {
if (searchResults.length === 0) return;
if (direction === 'next') {
setCurrentSearchIndex((prev) => (prev + 1) % searchResults.length);
} else {
setCurrentSearchIndex((prev) => (prev - 1 + searchResults.length) % searchResults.length);
}
// Navigate to the page with the search result
const targetPage = searchResults[currentSearchIndex].page;
setCurrentPage(targetPage);
};
// Theme classes
const themeClasses = {
light: 'reader-light-theme',
dark: 'reader-dark-theme',
sepia: 'reader-sepia-theme'
};
return (
<div className={`immersive-reader ${themeClasses[theme]}`}>
{/* Top Controls */}
<div className="reader-controls top-controls">
<div className="reader-header">
<h2>{book.title}</h2>
<p>by {book.author}</p>
</div>
<div className="reader-progress">
<div className="progress-bar">
<div
className="progress-fill"
style={{ width: `${(currentPage / book.totalPages) * 100}%` }}
></div>
</div>
<span className="progress-text">{currentPage} / {book.totalPages}</span>
</div>
<VSCodeButton appearance="icon" onClick={onClose} className="close-button">
<span aria-label="Close reader">×</span>
</VSCodeButton>
</div>
{/* Middle Content Area */}
<div className="reader-content-area">
{/* Sidebar */}
<div className="reader-sidebar">
<div className="sidebar-section">
<h3>Navigation</h3>
<div className="page-input">
<VSCodeTextField
value={currentPage.toString()}
onChange={(e) => handleGoToPage(parseInt(e.target.value) || currentPage)}
/>
<span>of {book.totalPages}</span>
</div>
<div className="nav-buttons">
<VSCodeButton onClick={() => handlePageChange('prev')} disabled={currentPage <= 1}>
Previous
</VSCodeButton>
<VSCodeButton onClick={() => handlePageChange('next')} disabled={currentPage >= book.totalPages}>
Next
</VSCodeButton>
</div>
</div>
<div className="sidebar-section">
<h3>Search</h3>
<div className="search-controls">
<VSCodeTextField
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
placeholder="Search in book..."
/>
{searchResults.length > 0 && (
<div className="search-navigation">
<VSCodeButton
onClick={() => handleSearchNavigation('prev')}
disabled={searchResults.length === 0}
>
</VSCodeButton>
<span>{currentSearchIndex + 1} of {searchResults.length}</span>
<VSCodeButton
onClick={() => handleSearchNavigation('next')}
disabled={searchResults.length === 0}
>
</VSCodeButton>
</div>
)}
</div>
</div>
<div className="sidebar-section">
<h3>Settings</h3>
<div className="settings-controls">
<div className="setting-row">
<label>Font Size:</label>
<input
type="range"
min="12"
max="24"
value={fontSize}
onChange={(e) => setFontSize(parseInt(e.target.value))}
/>
<span>{fontSize}px</span>
</div>
<div className="setting-row">
<label>Line Height:</label>
<select value={lineHeight} onChange={(e) => setLineHeight(parseFloat(e.target.value))}>
<option value={1.2}>Compact</option>
<option value={1.5}>Normal</option>
<option value={1.8}>Spacious</option>
</select>
</div>
<div className="setting-row">
<label>Theme:</label>
<select value={theme} onChange={(e) => setTheme(e.target.value as any)}>
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="sepia">Sepia</option>
</select>
</div>
<div className="setting-row">
<label>Mode:</label>
<select value={readingMode} onChange={(e) => setReadingMode(e.target.value as any)}>
<option value="continuous">Continuous</option>
<option value="paged">Paged</option>
</select>
</div>
<VSCodeCheckbox
checked={showBookmarks}
onChange={(e) => setShowBookmarks(e.target.checked)}
>
Show Bookmarks
</VSCodeCheckbox>
<VSCodeCheckbox
checked={showAnnotations}
onChange={(e) => setShowAnnotations(e.target.checked)}
>
Show Annotations
</VSCodeCheckbox>
</div>
</div>
<div className="sidebar-section">
<h3>Bookmarks</h3>
<div className="bookmarks-list">
{book.bookmarks.map(page => (
<div
key={page}
className={`bookmark-item ${page === currentPage ? 'active' : ''}`}
onClick={() => handleGoToPage(page)}
>
Page {page}
</div>
))}
</div>
</div>
</div>
{/* Main Content */}
<div className="reader-main-content">
<div
ref={contentRef}
className="content-display"
style={{
fontSize: `${fontSize}px`,
lineHeight: lineHeight,
}}
>
{/* Mock content - in real implementation this would render the actual book content */}
<div className="page-content">
<h1>Chapter {currentPage}: Sample Chapter Title</h1>
<p>
This is a sample paragraph demonstrating the immersive reading experience.
The text would flow naturally with proper typography and spacing based on
the selected settings. In a real implementation, this would render actual
book content from the selected file format (PDF, EPUB, or text).
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam auctor,
nisl eget ultricies tincidunt, nisl nisl aliquam nisl, eget ultricies
nisl nisl eget nisl. Nullam auctor, nisl eget ultricies tincidunt,
nisl nisl aliquam nisl, eget ultricies nisl nisl eget nisl.
</p>
<p>
Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</p>
<p>
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde
omnis iste natus error sit voluptatem accusantium doloremque laudantium,
totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi
architecto beatae vitae dicta sunt explicabo.
</p>
{showAnnotations && (
<div className="annotations-section">
<h4>Annotations on this page</h4>
{book.annotations
.filter(ann => ann.page === currentPage)
.map(ann => (
<div key={ann.id} className="annotation-item">
<p>{ann.text}</p>
<small>{ann.timestamp.toLocaleString()}</small>
</div>
))}
{isAddingAnnotation ? (
<div className="add-annotation-form">
<textarea
value={newAnnotation}
onChange={(e) => setNewAnnotation(e.target.value)}
placeholder="Add your annotation here..."
rows={3}
/>
<div className="annotation-actions">
<VSCodeButton onClick={handleAddAnnotation}>Save</VSCodeButton>
<VSCodeButton appearance="secondary" onClick={() => setIsAddingAnnotation(false)}>
Cancel
</VSCodeButton>
</div>
</div>
) : (
<VSCodeButton onClick={() => setIsAddingAnnotation(true)}>
Add Annotation
</VSCodeButton>
)}
</div>
)}
</div>
</div>
</div>
</div>
{/* Bottom Controls */}
<div className="reader-controls bottom-controls">
<VSCodeButton
onClick={() => handleBookmarkToggle(currentPage)}
appearance={book.bookmarks.includes(currentPage) ? 'primary' : 'secondary'}
>
{book.bookmarks.includes(currentPage) ? '★ Bookmarked' : '☆ Bookmark Page'}
</VSCodeButton>
<div className="reading-stats">
<span>Progress: {Math.round((currentPage / book.totalPages) * 100)}%</span>
<span>Estimated time: {(book.totalPages - currentPage) * 2} min left</span>
</div>
</div>
</div>
);
};
export default ImmersiveReader;

View file

@ -0,0 +1,351 @@
import React, { useState, useEffect } from 'react';
import { VSCodeButton, VSCodeDropdown, VSCodeOption, VSCodeTextField, VSCodeCheckbox } from '@vscode/webview-ui-toolkit/react';
interface AurelioSettings {
paradigm: 'standard' | 'toon' | 'tilth-dirac';
tokenCharacterization: boolean;
agentInteroperability: {
cline: boolean;
rooCode: boolean;
claudeCode: boolean;
copilot: boolean;
openCode: boolean;
};
brainSync: {
proxmoxEndpoint: string;
autoSync: boolean;
};
astParserLanguages: string[];
tokenMetricsDisplay: boolean;
advanced: {
resetDefaults: boolean;
};
}
const SettingsTab: React.FC = () => {
const [settings, setSettings] = useState<AurelioSettings>({
paradigm: 'standard',
tokenCharacterization: true,
agentInteroperability: {
cline: true,
rooCode: true,
claudeCode: true,
copilot: true,
openCode: true
},
brainSync: {
proxmoxEndpoint: 'https://mcp.portugalfuturista.org',
autoSync: true
},
astParserLanguages: ['typescript', 'python', 'rust', 'go', 'java', 'c', 'cpp'],
tokenMetricsDisplay: true,
advanced: {
resetDefaults: false
}
});
const [tokenMetrics, setTokenMetrics] = useState({
currentTokens: 0,
savedTokens: 0,
efficiencyPercent: 0
});
// Load settings from VS Code extension
useEffect(() => {
// In a real implementation, this would load from VS Code
// const loadedSettings = loadSettingsFromVscode();
// setSettings(loadedSettings);
// Simulate loading token metrics
setTokenMetrics({
currentTokens: 12450,
savedTokens: 3420,
efficiencyPercent: 21.6
});
}, []);
const handleSettingChange = (field: keyof AurelioSettings, value: any) => {
setSettings(prev => ({
...prev,
[field]: value
}));
};
const handleSubSettingChange = (parentField: keyof AurelioSettings, subField: string, value: any) => {
setSettings(prev => ({
...prev,
[parentField]: {
...(prev[parentField] as any),
[subField]: value
}
}));
};
const handleSaveSettings = () => {
// In a real implementation, this would send to VS Code extension
console.log('Saving settings:', settings);
window.vscode.postMessage({
command: 'saveAurelioSettings',
settings: settings
});
};
const handleSyncBrain = () => {
window.vscode.postMessage({
command: 'syncBrainNow'
});
};
const handleResetToDefaults = () => {
if (confirm('Are you sure you want to reset all settings to defaults?')) {
setSettings({
paradigm: 'standard',
tokenCharacterization: true,
agentInteroperability: {
cline: true,
rooCode: true,
claudeCode: true,
copilot: true,
openCode: true
},
brainSync: {
proxmoxEndpoint: 'https://mcp.portugalfuturista.org',
autoSync: true
},
astParserLanguages: ['typescript', 'python', 'rust', 'go', 'java', 'c', 'cpp'],
tokenMetricsDisplay: true,
advanced: {
resetDefaults: false
}
});
}
};
const languageOptions = [
'typescript', 'javascript', 'python', 'rust', 'go', 'java',
'c', 'cpp', 'ruby', 'php', 'csharp', 'swift', 'kotlin'
];
return (
<div className="settings-tab">
<h2>Aurelio Compiler Paradigm Settings</h2>
{/* Paradigm Selection */}
<div className="setting-group">
<h3>Compiler Paradigm</h3>
<div className="setting-row">
<label htmlFor="paradigm">Paradigm:</label>
<VSCodeDropdown
id="paradigm"
value={settings.paradigm}
onChange={(e) => handleSettingChange('paradigm', e.target.value as any)}
>
<VSCodeOption value="standard">Standard</VSCodeOption>
<VSCodeOption value="toon">TOON (Token-Optimized Object Notation)</VSCodeOption>
<VSCodeOption value="tilth-dirac">Tilth-Dirac (AST + Hash-Anchored)</VSCodeOption>
</VSCodeDropdown>
</div>
<p className="setting-description">
Select the compiler paradigm for optimizing AI agent interactions:
<ul>
<li><strong>Standard</strong>: Traditional JSON-based communication</li>
<li><strong>TOON</strong>: Table-like notation for arrays of objects (saves tokens)</li>
<li><strong>Tilth-Dirac</strong>: AST-aware file operations with hash-anchored editing</li>
</ul>
</p>
</div>
{/* Token Characterization */}
<div className="setting-group">
<h3>Token Characterization</h3>
<div className="setting-row">
<VSCodeCheckbox
checked={settings.tokenCharacterization}
onChange={(e) => handleSettingChange('tokenCharacterization', e.target.checked)}
>
Enable token characterization display
</VSCodeCheckbox>
</div>
<p className="setting-description">
Show live token usage metrics and efficiency indicators
</p>
</div>
{/* Agent Interoperability */}
<div className="setting-group">
<h3>Agent Interoperability</h3>
<div className="setting-row">
<VSCodeCheckbox
checked={settings.agentInteroperability.cline}
onChange={(e) => handleSubSettingChange('agentInteroperability', 'cline', e.target.checked)}
>
Cline
</VSCodeCheckbox>
<VSCodeCheckbox
checked={settings.agentInteroperability.rooCode}
onChange={(e) => handleSubSettingChange('agentInteroperability', 'rooCode', e.target.checked)}
>
Roo Code
</VSCodeCheckbox>
<VSCodeCheckbox
checked={settings.agentInteroperability.claudeCode}
onChange={(e) => handleSubSettingChange('agentInteroperability', 'claudeCode', e.target.checked)}
>
Claude Code
</VSCodeCheckbox>
<VSCodeCheckbox
checked={settings.agentInteroperability.copilot}
onChange={(e) => handleSubSettingChange('agentInteroperability', 'copilot', e.target.checked)}
>
GitHub Copilot
</VSCodeCheckbox>
<VSCodeCheckbox
checked={settings.agentInteroperability.openCode}
onChange={(e) => handleSubSettingChange('agentInteroperability', 'openCode', e.target.checked)}
>
OpenCode
</VSCodeCheckbox>
</div>
<p className="setting-description">
Enable compatibility with different AI coding assistants
</p>
</div>
{/* AST Parser Languages */}
<div className="setting-group">
<h3>AST Parser Languages</h3>
<div className="setting-row">
{languageOptions.map(lang => (
<VSCodeCheckbox
key={lang}
checked={settings.astParserLanguages.includes(lang)}
onChange={(e) => {
if (e.target.checked) {
handleSettingChange('astParserLanguages', [...settings.astParserLanguages, lang]);
} else {
handleSettingChange('astParserLanguages',
settings.astParserLanguages.filter(l => l !== lang)
);
}
}}
>
{lang.charAt(0).toUpperCase() + lang.slice(1)}
</VSCodeCheckbox>
))}
</div>
<p className="setting-description">
Languages supported by the Aurelio AST parser for smart file reading and searching
</p>
</div>
{/* Brain Sync Settings */}
<div className="setting-group">
<h3>Brain Sync Settings</h3>
<div className="setting-row">
<label htmlFor="proxmox-endpoint">Proxmox Endpoint:</label>
<VSCodeTextField
id="proxmox-endpoint"
value={settings.brainSync.proxmoxEndpoint}
onChange={(e) => handleSubSettingChange('brainSync', 'proxmoxEndpoint', e.target.value)}
/>
</div>
<div className="setting-row">
<VSCodeCheckbox
checked={settings.brainSync.autoSync}
onChange={(e) => handleSubSettingChange('brainSync', 'autoSync', e.target.checked)}
>
Enable auto-sync
</VSCodeCheckbox>
</div>
<div className="setting-row">
<VSCodeButton appearance="secondary" onClick={handleSyncBrain}>
Sync Brain Now
</VSCodeButton>
</div>
<p className="setting-description">
Configure synchronization with the central brain on Proxmox
</p>
</div>
{/* Token Metrics Display */}
<div className="setting-group">
<h3>Token Metrics Display</h3>
<div className="setting-row">
<VSCodeCheckbox
checked={settings.tokenMetricsDisplay}
onChange={(e) => handleSettingChange('tokenMetricsDisplay', e.target.checked)}
>
Show token metrics panel
</VSCodeCheckbox>
</div>
<div className="token-metrics-panel">
<h4>Current Session Metrics</h4>
<div className="metric-row">
<span>Current Tokens Used:</span>
<span>{tokenMetrics.currentTokens.toLocaleString()}</span>
</div>
<div className="metric-row">
<span>Tokens Saved (TOON/Tilth):</span>
<span>{tokenMetrics.savedTokens.toLocaleString()}</span>
</div>
<div className="metric-row">
<span>Efficiency Improvement:</span>
<span>{tokenMetrics.efficiencyPercent}%</span>
</div>
</div>
<p className="setting-description">
Display live token usage and efficiency metrics in the UI
</p>
</div>
{/* Advanced Settings */}
<div className="setting-group">
<h3>Advanced Settings</h3>
<div className="setting-row">
<VSCodeButton appearance="secondary" onClick={handleResetToDefaults}>
Reset to Defaults
</VSCodeButton>
</div>
<p className="setting-description">
Reset all settings to their default values
</p>
</div>
{/* Save Button */}
<div className="setting-group">
<VSCodeButton appearance="primary" onClick={handleSaveSettings}>
Save Settings
</VSCodeButton>
</div>
{/* Imported Techniques Dashboard */}
<div className="setting-group">
<h3>Imported Techniques Provenance</h3>
<div className="techniques-dashboard">
<div className="technique-card">
<h4>TOON (Token-Optimized Object Notation)</h4>
<p>Reduces token usage by converting arrays of uniform objects to table-like format</p>
<p className="stat">Avg. Savings: 30-60%</p>
</div>
<div className="technique-card">
<h4>Tilth AST-Aware Operations</h4>
<p>Uses tree-sitter to provide structural outlines for large files instead of full content</p>
<p className="stat">Avg. Savings: 50-80% for large files</p>
</div>
<div className="technique-card">
<h4>Dirac Hash-Anchored Editing</h4>
<p>Prevents edit drift by validating content hashes before applying changes</p>
<p className="stat">Precision: Sub-line accuracy</p>
</div>
<div className="technique-card">
<h4>Session Deduplication</h4>
<p>Prevents showing the same code definitions multiple times in a session</p>
<p className="stat">Reduces redundancy by 40-70%</p>
</div>
</div>
</div>
</div>
);
};
export default SettingsTab;