git-contextor
Version:
A code context tool with vector search and real-time monitoring, with optional Git integration.
227 lines (221 loc) • 12.5 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Git Contextor - Dashboard</title>
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
</head>
<body>
<div class="container">
<header>
<h1>Git Contextor</h1>
<nav id="main-nav">
<a href="/index.html" class="active">Dashboard</a>
<a href="/metrics.html">Metrics</a>
<a href="/docs.html">Docs</a>
<a href="/config.html">Config</a>
</nav>
</header>
<main>
<nav id="view-nav">
<a href="#dashboard" class="active">Dashboard</a>
<a href="#activity">Live Activity</a>
<a href="#files">File Browser</a>
<a href="#sharing">Sharing</a>
</nav>
<!-- Dashboard View -->
<div id="view-dashboard">
<div class="dashboard-grid">
<section id="status-overview" class="card">
<h2>Status Overview</h2>
<div class="status-grid">
<div><strong>Repository:</strong> <span id="repo-name">Loading...</span></div>
<div><strong>Path:</strong> <span id="repo-path">Loading...</span></div>
<div><strong>Service Status:</strong> <span id="service-status">Loading...</span></div>
<div>
<strong>File Watcher:</strong>
<span id="watcher-status">Loading...</span>
<label class="toggle-switch">
<input type="checkbox" id="watcher-toggle">
<span class="slider"></span>
</label>
</div>
<div><strong>Total Chunks:</strong> <span id="total-chunks">Loading...</span></div>
</div>
</section>
<section id="search-interface" class="card">
<h2>Semantic Search</h2>
<form id="search-form">
<div class="search-input-group">
<input type="text" id="search-query" placeholder="Enter your search query..." required>
<div class="search-options">
<label for="max-tokens">Max Tokens:</label>
<input type="number" id="max-tokens" value="2048" min="256" step="256">
</div>
<button type="submit">Search</button>
</div>
</form>
<div id="search-results-container" style="display: none;">
<h3>Results</h3>
<div id="search-results"></div>
</div>
<div id="api-snippet-container" style="display: none;">
<h3>API Snippets</h3>
<div class="tabs">
<button class="tab-button active" data-lang="curl">cURL</button>
<button class="tab-button" data-lang="node">Node.js</button>
<button class="tab-button" data-lang="python">Python</button>
</div>
<div id="snippet-content">
<pre id="snippet-curl" class="snippet active"></pre>
<pre id="snippet-node" class="snippet"></pre>
<pre id="snippet-python" class="snippet"></pre>
</div>
</div>
</section>
<section id="chat-interface" class="card full-width">
<h2>AI Chat</h2>
<form id="chat-form">
<div class="search-input-group">
<textarea id="chat-query" placeholder="Ask the AI about your repository..." required rows="3"></textarea>
<button type="submit">Ask</button>
</div>
</form>
<div id="chat-results-container" style="display: none;">
<h3>🤖 AI Response</h3>
<div id="chat-results" class="docs-content"></div>
<div id="chat-context-container" style="display: none; margin-top: 20px; border-top: 1px solid var(--border-color); padding-top: 15px;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<h4 style="margin: 0; font-size: 1.1em; color: var(--subtle-text-color);">Context Used (<span id="chat-context-count">0</span> chunks)</h4>
<button id="toggle-context-btn" class="button-secondary">Show</button>
</div>
<div id="chat-context-details" style="display: none; margin-top: 15px;">
<!-- Context cards will be rendered here by JS -->
</div>
</div>
</div>
</section>
<section id="summary-panel" class="card full-width">
<div class="panel-header">
<h2>Collection Summary</h2>
<button id="update-summary-btn" class="button">Update Summary</button>
</div>
<div class="panel-content">
<div id="summary-content" class="docs-content">Loading...</div>
</div>
</section>
</div>
</div>
<!-- Live Activity View -->
<div id="view-activity" class="hidden">
<section id="live-feed" class="card">
<h2>Live Activity Feed</h2>
<ul id="activity-log">
<li>Waiting for events...</li>
</ul>
</section>
</div>
<!-- File Browser View -->
<div id="view-files" class="hidden">
<section id="file-browser" class="card">
<h2>File Browser</h2>
<div class="file-browser-container">
<div id="file-tree-panel" class="file-tree-panel">
<p>Loading files...</p>
</div>
<div id="file-viewer-panel" class="file-viewer-panel" style="display: none;">
<div class="file-viewer-header">
<h3 id="file-viewer-filename"></h3>
<div class="file-viewer-actions">
<button id="file-ask-ai-btn" class="button-secondary">Ask AI about this file</button>
</div>
</div>
<div id="file-viewer-content" class="docs-content"></div>
</div>
</div>
</section>
</div>
<!-- Sharing View -->
<div id="view-sharing" class="hidden">
<section id="sharing-interface" class="card">
<h2>Repository Sharing</h2>
<div class="sharing-grid">
<div id="create-share-form-container">
<h3>Create a New Share</h3>
<form id="share-form">
<div class="form-group">
<label for="share-description">Description:</label>
<input type="text" id="share-description" placeholder="E.g., External code review" required>
</div>
<div class="form-group">
<label for="share-duration">Duration:</label>
<select id="share-duration">
<option value="1h" selected>1 Hour</option>
<option value="24h">24 Hours</option>
<option value="7d">7 Days</option>
</select>
</div>
<button type="submit">Create Share</button>
</form>
<div id="share-create-result" style="display:none;">
<h4>Share Created!</h4>
<pre></pre>
</div>
</div>
<div id="active-shares-container">
<h3>Active Shares <button id="refresh-shares-btn" title="Refresh List">🔄</button></h3>
<ul id="active-shares-list">
<li>Loading...</li>
</ul>
</div>
</div>
<div class="tunnel-container">
<h3>Public Tunnel</h3>
<p>Expose your local service to the internet for external collaborators. This allows you to share a public URL.</p>
<div id="tunnel-controls">
<div class="form-group">
<label for="tunnel-service">Service:</label>
<select id="tunnel-service">
<option value="corrently" selected>tunnel.corrently.cloud (recommended)</option>
<option value="localtunnel">localtunnel (free)</option>
<option value="managed">Managed Tunneling (professional)</option>
<option value="ngrok" disabled>ngrok (coming soon)</option>
<option value="serveo" disabled>serveo (coming soon)</option>
</select>
</div>
<div id="managed-tunnel-options" style="display:none;">
<div class="form-group">
<label for="tunnel-description">Description:</label>
<input type="text" id="tunnel-description" placeholder="Git Contextor Share">
</div>
<div class="managed-tunnel-status">
<p><strong>Status:</strong> <span id="managed-tunnel-auth-status">Not authenticated</span></p>
<button id="managed-tunnel-login-btn" style="display:none;">Configure Service</button>
</div>
</div>
<button id="tunnel-toggle-btn">Start Tunnel</button>
</div>
<div id="tunnel-status-container" style="display:none;">
<h4>Tunnel Status</h4>
<p><strong>Status:</strong> <span id="tunnel-status"></span></p>
<p><strong>Public URL:</strong> <span id="tunnel-url"></span></p>
<p id="tunnel-password-container" style="display:none;"><strong>Password:</strong> <span id="tunnel-password" style="font-weight: bold; color: var(--error-color);"></span></p>
<div id="tunnel-hint" class="hint" style="display:none;">
<strong>Note:</strong> If the tunnel URL asks for a password, it's likely a security check from the `localtunnel` service. Please enter your public IP address to proceed. You can find your IP by searching "what is my ip" in your browser.
</div>
</div>
</div>
</section>
</div>
</main>
<footer>
<p>Powered by <a href="https://github.com/stromdao/git-contextor" target="_blank">Git Contextor</a> © 2025 by <a href="https://stromdao.de/" target="_blank">STROMDAO GmbH</a></p>
</footer>
</div>
<script src="/js/app.js"></script>
</body>
</html>