const state = { manifest: null, node: null, selected: null, casefile: null, activeFile: 'src/agent.ts', files: { 'agent.ts': `import { ChatMessage, ModelAdapter } from './types'; import { LocalModelRouter } from './router'; export class AgentRuntime { constructor(private readonly router: LocalModelRouter) {} async review(task: string) { const lanes = this.router.plan(task); return this.router.runBounded(lanes); } }`, 'router.ts': `export class LocalModelRouter { constructor(private readonly registry: ModelRegistry) {} plan(task: string) { return ['research', 'build', 'verify'].map(role => ({ role, task })); } async runBounded(lanes: Lane[]) { // Each lane receives only the context it needs and returns a reviewable artifact. return this.registry.executeSequentially(lanes, { maxTurns: 4, approval: true }); } }`, 'models.ts': `export type ModelRole = 'research' | 'build' | 'verify'; export interface ModelManifest { id: string; status: 'experimental' | 'ready' | 'pending'; roles: ModelRole[]; runtime: 'llama.cpp' | 'ollama' | 'openai-compatible'; endpoint: string; }`, 'types.ts': `export interface Lane { role: 'research' | 'build' | 'verify'; task: string; claims?: string[]; patch?: string; confidence?: number; }`, 'README.md': '# AIDE\n\nLocal-first development with explicit model lanes and reviewable patches.' }}; const $ = selector => document.querySelector(selector); const esc = value => String(value).replace(/[&<>"']/g, char => ({ '&':'&', '<':'<', '>':'>', '"':'"', "'":''' }[char])); const patchValid = value => /^diff --git\s+\S+\s+\S+/m.test(value) && /^---\s+/m.test(value) && /^\+\+\+\s+/m.test(value) && !/^```/m.test(value); function openFile(name) { const text = state.files[name] || state.files['agent.ts']; state.activeFile = `src/${name}`; $('#code').textContent = text; $('#line-numbers').textContent = text.split('\n').map((_, index) => index + 1).join('\n'); document.querySelectorAll('[data-file]').forEach(button => button.classList.toggle('active', button.dataset.file === name)); } async function saveFile() { try { const response = await fetch('http://127.0.0.1:4777/api/file/write', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ path: state.activeFile, content: $('#code').textContent, approved: true }) }); const result = await response.json(); if (!response.ok) throw new Error(result.error || 'file write rejected'); appendLog('WORKSPACE', `${result.path} saved atomically after explicit approval.`); } catch (error) { appendLog('WORKSPACE', `Save blocked: ${error.message}. Start the local daemon and open a trusted workspace.`, 'warning'); } } function renderModels() { const list = $('#model-list'); const lanes = $('#lane-grid'); list.innerHTML = ''; lanes.innerHTML = ''; state.manifest.models.forEach(model => { const installed = JSON.parse(localStorage.getItem(`aide.model.${model.id}`) || 'null'); const visibleStatus = installed ? 'imported' : model.status; const roles = model.roles.join(' / '); const item = document.createElement('button'); item.className = 'model-item'; item.innerHTML = `${esc(model.name)}${esc(model.format)} | ${esc(visibleStatus)} | ${esc(roles)}${installed ? 'REPLACE' : 'IMPORT'}`; item.onclick = () => selectModel(model); item.querySelector('.pack-action').onclick = event => { event.stopPropagation(); importModel(model); }; list.appendChild(item); const lane = document.createElement('button'); lane.className = `lane ${model.status}`; lane.innerHTML = `${esc(model.lane.toUpperCase())}${esc(model.name)}${esc(roles)}`; lane.onclick = () => selectModel(model); lanes.appendChild(lane); }); } async function importModel(model) { const input = $('#model-file-input'); input.value = ''; input.onchange = async () => { const file = input.files?.[0]; if (!file) return; const digest = await crypto.subtle.digest('SHA-256', await file.arrayBuffer()); const hash = [...new Uint8Array(digest)].map(byte => byte.toString(16).padStart(2, '0')).join(''); const record = { id: model.id, name: file.name, bytes: file.size, sha256: hash, imported_at: new Date().toISOString(), source_repo: model.source_revision }; localStorage.setItem(`aide.model.${model.id}`, JSON.stringify(record)); appendLog('MODEL PACK', `${model.name} imported locally. SHA-256: ${hash}. Runtime attachment is still required before inference.`); renderModels(); selectModel(model); }; let communityStore = { projects: [], issues: [], discussions: [], marketplace: [] }; input.click(); } function selectModel(model) { state.selected = model; $('#selected-model').textContent = model.name; $('#selected-detail').textContent = `${model.format} | ${model.status} | ${model.description}`; $('#runtime-name').textContent = model.runtime; } function appendLog(role, text, type = '') { const log = $('#collab-log'); if (log.querySelector('.empty-state')) log.innerHTML = ''; const entry = document.createElement('div'); entry.className = `log-entry ${type}`; entry.innerHTML = `${esc(role)}

${esc(text)}

`; log.appendChild(entry); log.scrollTop = log.scrollHeight; } async function requestLocal(model, messages) { const response = await fetch(`${model.endpoint}/chat/completions`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: model.model, messages, temperature: model.temperature, max_tokens: model.max_tokens }) }); if (!response.ok) throw new Error(`runtime returned HTTP ${response.status}`); const data = await response.json(); return data.choices?.[0]?.message?.content || 'Runtime returned no content.'; } async function runReview() { const task = $('#input').value.trim() || 'Review the local provider router for safer fallback behavior.'; const runnable = model => ['ready', 'experimental'].includes(model.status) && model.endpoint?.startsWith('http'); const ready = state.manifest.models.filter(runnable); const research = state.manifest.models.find(model => model.id === 'fsi-tinyliquid-training' && model.status === 'ready') || state.manifest.models.find(model => model.lane === 'research' && runnable(model)) || ready[0]; const builder = state.manifest.models.find(model => model.lane === 'build' && runnable(model)) || ready[0]; const verifier = state.manifest.models.find(model => model.lane === 'verify') || builder; $('#review-button').disabled = true; $('#review-button').textContent = 'RUNNING...'; $('#collab-log').innerHTML = ''; appendLog('COORDINATOR', `Task accepted with a four-turn maximum: ${task}`); try { if (research.status === 'pending') throw new Error('Research lane is not configured. Add a local endpoint or checkpoint first.'); const findings = await requestLocal(research, [{ role: 'system', content: research.system_prompt }, { role: 'user', content: task }]); appendLog('RESEARCH', findings); if (builder.status === 'pending') throw new Error('Coding lane is not configured. Install a coding checkpoint before applying patches.'); let patch = await requestLocal(builder, [{ role: 'system', content: builder.system_prompt }, { role: 'user', content: `Task: ${task}\nResearch findings:\n${findings}\nReturn a unified diff only.` }]); if (!patchValid(patch)) { appendLog('REPAIR', 'Builder output was not a valid unified diff. Requesting one bounded repair.', 'warning'); patch = await requestLocal(builder, [{ role: 'system', content: 'Convert the raw response into one valid unfenced unified diff. Preserve intent. Return only the diff. Do not invent files or claim tests passed.' }, { role: 'user', content: `Task: ${task}\nRaw response:\n${patch}` }]); } if (!patchValid(patch)) throw new Error('Patch repair failed structural validation; no files changed.'); appendLog('BUILD', patch, 'patch'); if (verifier.status === 'pending') throw new Error('Verifier lane is not configured.'); const verdict = await requestLocal(verifier, [{ role: 'system', content: verifier.system_prompt }, { role: 'user', content: `Task: ${task}\nProposed patch:\n${patch}\nReturn APPROVE, REJECT, or NEEDS-EVIDENCE with reasons.` }]); appendLog('VERIFY', verdict, verdict.includes('APPROVE') ? 'approved' : 'warning'); appendLog('COORDINATOR', 'No files were changed. Review and approve the patch before applying it.'); } catch (error) { appendLog('STOPPED', error.message, 'warning'); } finally { await saveReplay('review-complete'); $('#review-button').disabled = false; $('#review-button').textContent = 'START BOUNDED REVIEW'; } } async function testRuntime() { const model = state.selected || state.manifest.models.find(item => item.status !== 'pending'); if (!model) return appendLog('RUNTIME', 'No configured local model endpoint.', 'warning'); appendLog('RUNTIME', `Testing ${model.name} at ${model.endpoint}...`); try { const response = await fetch(`${model.endpoint}/models`); appendLog('RUNTIME', response.ok ? 'Local runtime reachable. Model remains subject to capability checks.' : `Runtime returned HTTP ${response.status}.`, response.ok ? 'approved' : 'warning'); } catch (error) { appendLog('RUNTIME', 'Offline shell is healthy, but no local HTTP runtime is reachable. This is expected until the adapter is started.', 'warning'); } } async function startRuntime() { const model = state.selected; if (!model) return appendLog('RUNTIME', 'Select a model pack first.', 'warning'); try { const response = await fetch('http://127.0.0.1:4777/api/models/start', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: model.id }) }); const result = await response.json(); if (!response.ok) throw new Error(result.error || 'runtime start failed'); appendLog('RUNTIME', `${model.name} is starting at ${result.endpoint}.`); setTimeout(testRuntime, 1500); } catch (error) { appendLog('RUNTIME', `Local daemon unavailable: ${error.message}. Start daemon/server.mjs first.`, 'warning'); } } function sendChat() { const input = $('#input'); const value = input.value.trim(); if (!value) return; $('#chat').insertAdjacentHTML('beforeend', `

YOU
${esc(value)}

AIDE
Use START BOUNDED REVIEW to send this task through the research, build, and verify lanes. No files will change automatically.

`); input.value = ''; } function localNodeId() { let id = localStorage.getItem('aide.node.id'); if (!id) { id = crypto.randomUUID(); localStorage.setItem('aide.node.id', id); } return id; } function renderCasefile() { const status = $('#case-status'); const list = $('#evidence-list'); if (!state.casefile) { status.textContent = 'No case open.'; list.textContent = ''; return; } status.innerHTML = `CASE ${esc(state.casefile.id)}
${state.casefile.evidence.length} evidence item(s)
Local-only provenance ledger`; list.innerHTML = state.casefile.evidence.map(item => `
${esc(item.name)}
${esc(item.bytes)} bytes | SHA-256 ${esc(item.hash.slice(0, 12))}...
dates: ${esc(item.dates.join(', ') || 'none detected')}
`).join(''); } function renderCommunity(tab = 'projects') { const entries = communityStore[tab] || []; $('#community-feed').innerHTML = `
LOCAL CACHE / SYNC OFF
${entries.map((entry, index) => `
${esc(entry.title)}
${esc(entry.detail)}
${esc(entry.boundary || entry.status || 'local')}
`).join('')}`; document.querySelectorAll('[data-community-tab]').forEach(button => button.style.color = button.dataset.communityTab === tab ? '#72ff9e' : '#718994'); document.querySelectorAll('[data-community-remove]').forEach(button => button.onclick = () => removeCommunityItem(tab, Number(button.dataset.communityRemove))); } async function removeCommunityItem(type, index) { try { await fetch('http://127.0.0.1:4777/api/community/items', { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ type, index }) }); await loadCommunity(); } catch (error) { appendLog('COMMUNITY', `Could not remove local item: ${error.message}`, 'warning'); } } async function loadCommunity() { try { const response = await fetch('http://127.0.0.1:4777/api/community'); if (response.ok) communityStore = await response.json(); } catch { /* offline cache remains empty until the daemon is running */ } renderCommunity(); } async function addCommunityIssue() { const title = $('#community-title').value.trim(); if (!title) return; try { const response = await fetch('http://127.0.0.1:4777/api/community/items', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ type: $('#community-type').value, item: { title, detail: 'Created locally from AIDE.' } }) }); if (!response.ok) throw new Error('daemon rejected item'); $('#community-title').value = ''; await loadCommunity(); appendLog('COMMUNITY', `Issue created locally: ${title}`); } catch (error) { appendLog('COMMUNITY', `Local daemon unavailable: ${error.message}`, 'warning'); } } async function startTool(kind, id, label) { try { const response = await fetch(`http://127.0.0.1:4777/api/${kind}/start`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id }) }); const result = await response.json(); if (!response.ok) throw new Error(result.error || `${label} failed`); $('#tool-status').textContent = `${label}: ${result.status}`; appendLog('TOOLCHAIN', `${label} ${result.status}.`); if (kind === 'lsp') { const init = await fetch('http://127.0.0.1:4777/api/lsp/request', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, message: { method: 'initialize', params: { processId: null, rootUri: null, capabilities: {} } } }) }); const initialized = await fetch('http://127.0.0.1:4777/api/lsp/notify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, message: { method: 'initialized', params: {} } }) }); appendLog('LSP', init.ok && initialized.ok ? 'initialize handshake completed.' : 'initialize handshake failed.', init.ok && initialized.ok ? '' : 'warning'); } if (kind === 'dap') { const init = await fetch('http://127.0.0.1:4777/api/dap/request', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, request: { command: 'initialize', arguments: { clientID: 'aide', clientName: 'AIDE', adapterID: id, linesStartAt1: true, columnsStartAt1: true, pathFormat: 'path' } } }) }); const payload = await init.json().catch(() => ({})); const capabilities = Object.keys(payload.body || {}).filter(key => key.startsWith('supports')); $('#debug-status').textContent = init.ok ? `Adapter ready: ${capabilities.length} capabilities.` : 'Adapter initialize failed.'; appendLog('DAP', init.ok ? `initialize handshake completed; ${capabilities.length} capabilities reported.` : 'initialize request failed.', init.ok ? '' : 'warning'); } } catch (error) { $('#tool-status').textContent = `${label}: unavailable`; appendLog('TOOLCHAIN', `${label} unavailable: ${error.message}`, 'warning'); } } async function checkActiveFile() { try { const content = $('#code').textContent; const uri = `file:///workspace/${state.activeFile}`; const open = await fetch('http://127.0.0.1:4777/api/lsp/notify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 'typescript', message: { method: 'textDocument/didOpen', params: { textDocument: { uri, languageId: 'typescript', version: 1, text: content } } } }) }); if (!open.ok) throw new Error('LSP is not running'); const response = await fetch('http://127.0.0.1:4777/api/lsp/request', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 'typescript', message: { method: 'textDocument/completion', params: { textDocument: { uri }, position: { line: 0, character: 0 } } } }) }); const result = await response.json(); if (!response.ok) throw new Error(result.error?.message || 'completion request failed'); const count = result.result?.items?.length ?? result.result?.length ?? 0; appendLog('LSP', `Active file analyzed. Completion items returned: ${count}.`); } catch (error) { appendLog('LSP', error.message, 'warning'); } } async function lspAction(action) { const uri = `file:///workspace/${state.activeFile}`; const base = { textDocument: { uri }, position: { line: 0, character: 0 } }; const requests = { hover: { method: 'textDocument/hover', params: base }, definition: { method: 'textDocument/definition', params: base }, rename: { method: 'textDocument/rename', params: { ...base, newName: 'AIDE_RENAMED' } }, formatting: { method: 'textDocument/formatting', params: { textDocument: { uri }, options: { tabSize: 2, insertSpaces: true } } } }; try { const response = await fetch('http://127.0.0.1:4777/api/lsp/request', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 'typescript', message: requests[action] }) }); const result = await response.json(); if (!response.ok) throw new Error(result.error?.message || 'LSP request failed'); appendLog('LSP', `${action}: ${JSON.stringify(result.result || null).slice(0, 500)}`); } catch (error) { appendLog('LSP', `${action} blocked: ${error.message}`, 'warning'); } } async function debugActiveFile() { if (!state.activeFile.endsWith('.py')) { $('#debug-status').textContent = 'Blocked: active file is not Python.'; appendLog('DAP', 'Debug launch blocked because the active file is not Python.', 'warning'); return; } try { const response = await fetch('http://127.0.0.1:4777/api/dap/request', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 'python-debugpy', request: { command: 'launch', arguments: { program: `/workspace/${state.activeFile}`, cwd: '/workspace', stopOnEntry: true } } }) }); const result = await response.json(); if (!response.ok || result.success === false) throw new Error(result.message || 'debug launch rejected'); $('#debug-status').textContent = 'Debug launch requested; waiting for entry stop.'; appendLog('DAP', 'Debug launch requested for the active Python file.'); } catch (error) { $('#debug-status').textContent = `Debug blocked: ${error.message}`; appendLog('DAP', error.message, 'warning'); } } async function refreshDebugThreads() { try { const response = await fetch('http://127.0.0.1:4777/api/dap/request', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 'python-debugpy', request: { command: 'threads', arguments: {} } }) }); const result = await response.json(); if (!response.ok || result.error) throw new Error(result.error?.format || 'debug adapter is not running'); const count = result.body?.threads?.length || 0; $('#debug-status').textContent = `Debug threads: ${count}. Stack/variables populate after launch.`; appendLog('DAP', `Threads refreshed: ${count}.`); } catch (error) { appendLog('DAP', error.message, 'warning'); } } async function trainingRequest(action, payload = {}) { try { const response = await fetch(`http://127.0.0.1:4777/api/training/${action}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const result = await response.json(); if (!response.ok) throw new Error(result.error || 'Training Room request failed'); $('#training-status').textContent = result.status === 'running' ? `Running: ${result.id}` : `Training Room: ${result.status}`; appendLog('TRAINING', JSON.stringify(result)); } catch (error) { $('#training-status').textContent = `Blocked: ${error.message}`; appendLog('TRAINING', error.message, 'warning'); } } async function refreshTrainingStatus() { try { const response = await fetch('http://127.0.0.1:4777/api/training/status'); if (!response.ok) return; const result = await response.json(); const active = result.active ? `running: ${result.active.id}` : 'idle'; const last = result.logs?.at(-1)?.line || 'no log output'; $('#training-status').textContent = `Training Room ${active} | ${result.jobs.length} job(s) | ${last.slice(0, 100)}`; } catch { /* daemon is optional while the static shell is offline */ } } async function saveReplay(status = 'verified') { try { await fetch('http://127.0.0.1:4777/api/replays', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ task_class: 'code-change', model: state.selected?.id || 'unknown', status, checks: { human_approval_required: true, source_exported: false } }) }); } catch { /* replay is optional while daemon is offline */ } } async function compareModels() { $('#arena-status').textContent = 'Running models sequentially...'; try { const response = await fetch('http://127.0.0.1:4777/api/arena/run', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ approved: true }) }); const result = await response.json(); if (!response.ok) throw new Error(result.error || 'arena failed'); $('#arena-status').textContent = result.winner ? `Winner: ${result.winner.model} (${(result.winner.score * 100).toFixed(1)}%, avg ${result.winner.latency_ms}ms)` : 'No model completed.'; appendLog('MODEL ARENA', 'Live sequential comparison complete. Scores are benchmark-local only.'); } catch (error) { $('#arena-status').textContent = `Arena blocked: ${error.message}`; appendLog('MODEL ARENA', error.message, 'warning'); } } async function digestFile(file) { const buffer = await file.arrayBuffer(); const digest = await crypto.subtle.digest('SHA-256', buffer); const hash = [...new Uint8Array(digest)].map(byte => byte.toString(16).padStart(2, '0')).join(''); const text = new TextDecoder().decode(buffer); const dates = [...new Set(text.match(/\b(?:19|20)\d{2}(?:[-/]\d{1,2}(?:[-/]\d{1,2})?)?\b/g) || [])].slice(0, 20); return { name: file.name, bytes: file.size, hash, dates, imported_at: new Date().toISOString() }; } async function importEvidence(event) { if (!state.casefile) { appendLog('CASEFILE', 'Create a case before importing evidence.', 'warning'); event.target.value = ''; return; } for (const file of event.target.files) state.casefile.evidence.push(await digestFile(file)); localStorage.setItem(`aide.case.${state.casefile.id}`, JSON.stringify(state.casefile)); renderCasefile(); appendLog('CASEFILE', `${event.target.files.length} evidence item(s) imported locally. Hashes and date anchors recorded; no network request made.`); event.target.value = ''; } function renderNode() { if (!state.node) return; const id = localStorage.getItem('aide.node.id'); $('#node-status').innerHTML = `LOCAL-FIRST
Network: ${esc(state.node.network_default)}
Private data: ${esc(state.node.replication.private)}
Group sync: ${esc(state.node.capabilities.encrypted_group_sync ? 'enabled' : 'disabled')}
Node ID: ${id ? esc(id.slice(0, 13) + '...') : 'not created'}`; } async function boot() { try { const response = await fetch('models/manifest.json', { cache: 'no-store' }); state.manifest = await response.json(); } catch (error) { state.manifest = { models: [] }; appendLog('BOOT', 'Could not load models/manifest.json.', 'warning'); } try { const nodeResponse = await fetch('community/node-manifest.json', { cache: 'no-store' }); state.node = await nodeResponse.json(); renderNode(); } catch (error) { $('#node-status').textContent = 'Node policy unavailable.'; } renderModels(); const firstReady = state.manifest.models.find(model => model.status !== 'pending'); if (firstReady) selectModel(firstReady); openFile('agent.ts'); document.querySelectorAll('[data-file]').forEach(button => button.onclick = () => openFile(button.dataset.file)); $('#review-button').onclick = runReview; $('#save-file').onclick = saveFile; $('#connection-button').onclick = startRuntime; $('#send-button').onclick = sendChat; $('#node-button').onclick = () => { localNodeId(); renderNode(); appendLog('NODE', 'Local identity created. No network connection or private data was shared.'); }; $('#case-button').onclick = () => { state.casefile = { id: `AIDE-${new Date().toISOString().slice(0, 10)}-${crypto.randomUUID().slice(0, 8)}`, evidence: [], created_at: new Date().toISOString(), boundary: 'private' }; localStorage.setItem(`aide.case.${state.casefile.id}`, JSON.stringify(state.casefile)); renderCasefile(); appendLog('CASEFILE', `Created ${state.casefile.id}. Boundary: private. Evidence remains on this device.`); }; $('#evidence-input').onchange = importEvidence; document.querySelectorAll('[data-community-tab]').forEach(button => button.onclick = () => renderCommunity(button.dataset.communityTab)); $('#community-add').onclick = addCommunityIssue; $('#lsp-button').onclick = () => startTool('lsp', 'typescript', 'TypeScript LSP'); $('#lsp-check').onclick = checkActiveFile; document.querySelectorAll('[data-lsp-action]').forEach(button => button.onclick = () => lspAction(button.dataset.lspAction)); $('#dap-button').onclick = () => startTool('dap', 'python-debugpy', 'Python DAP'); $('#debug-file').onclick = debugActiveFile; $('#debug-threads').onclick = refreshDebugThreads; $('#training-verify').onclick = () => trainingRequest('start', { id: 'verify-release', approved: true }); $('#training-stop').onclick = () => trainingRequest('stop'); $('#arena-button').onclick = compareModels; refreshTrainingStatus(); setInterval(refreshTrainingStatus, 5000); loadCommunity(); $('#input').onkeydown = event => { if (event.key === 'Enter') sendChat(); }; } boot();