<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Artydev Coding Terminal</title>
<!-- External Stylesheets -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@webtui/css/dist/base.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@webtui/theme-catppuccin/dist/catppuccin.css">
<style>
body {
margin: 0;
background: #0b0f14;
font-family: monospace;
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* --- FILLED BLOCK ASCII HEADER (CENTERED) --- */
.banner-header {
background: #0e121a;
border-bottom: 1px solid rgba(255, 255, 255, 0.04);
padding: 14px 16px 10px 16px;
user-select: none;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.ascii-title {
margin: 0;
font-family: monospace;
white-space: pre;
line-height: 1.1;
font-size: 11px;
color: #89b4fa; /* Catppuccin Blue */
text-shadow: 0 0 10px rgba(137, 180, 250, 0.25);
}
.sub-tagline {
margin-top: 6px;
font-size: 11px;
color: #585b70;
}
/* --- TMUX STYLE MULTIPLEXER BAR --- */
.session-bar {
background: #11151c;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
padding: 6px 12px;
display: flex;
gap: 15px;
font-size: 13px;
user-select: none;
align-items: center;
overflow-x: auto;
}
.session-wrapper {
display: inline-flex;
align-items: center;
gap: 4px;
color: #7f849c;
}
.session-tab {
cursor: pointer;
white-space: nowrap;
}
.session-tab.active {
color: #a6e3a1; /* Catppuccin Green */
font-weight: bold;
}
.session-tab.active::before { content: "["; color: #7aa2f7; }
.session-tab.active::after { content: "]*"; color: #7aa2f7; }
/* Inline Rename Editor Box Styling */
.rename-input {
background: #1e1e2e;
border: 1px solid #7aa2f7;
color: #a6e3a1;
font-family: monospace;
font-size: 13px;
padding: 0 4px;
width: 100px;
outline: none;
}
/* Subtle Delete Action Elements */
.delete-btn {
color: #585b70;
cursor: pointer;
font-size: 11px;
padding: 0 2px;
transition: color 0.15s ease;
display: none;
}
.session-wrapper:hover .delete-btn {
display: inline-block;
}
.delete-btn:hover {
color: #f38ba8 !important;
}
.bar-actions-group {
margin-left: auto;
display: flex;
gap: 16px;
align-items: center;
}
/* Unintrusive Model Selector UX */
.model-selector-wrapper {
display: flex;
align-items: center;
gap: 6px;
color: #94e2d5; /* Teal styling */
font-size: 12px;
}
.model-select-native {
background: #1e1e2e;
color: #94e2d5;
border: 1px solid rgba(148, 226, 213, 0.2);
font-family: monospace;
font-size: 11px;
padding: 2px 6px;
border-radius: 3px;
outline: none;
cursor: pointer;
}
.model-select-native:focus {
border-color: #94e2d5;
}
.new-session-btn {
color: #f5c2e7;
cursor: pointer;
font-weight: bold;
white-space: nowrap;
}
.wipe-workspace-btn {
color: #f38ba8; /* Warning Red */
cursor: pointer;
font-weight: normal;
white-space: nowrap;
opacity: 0.6;
transition: opacity 0.15s ease;
}
.wipe-workspace-btn:hover {
opacity: 1;
text-shadow: 0 0 8px rgba(243, 139, 168, 0.2);
}
/* --- PRIMARY TERMINAL AREA --- */
.terminal {
flex: 1;
display: flex;
flex-direction: column;
padding: 16px;
box-sizing: border-box;
overflow: hidden;
}
#log {
flex: 1;
overflow-y: auto;
padding-right: 8px;
}
.line {
white-space: pre-wrap;
margin: 2px 0;
}
.user { color: #a6e3a1; }
.ai { color: #f9e2af; }
.sys { color: #7aa2f7; }
.err { color: #f38ba8; }
.tool { color: #f5c2e7; }
.input-row {
display: flex;
gap: 10px;
align-items: center;
border-top: 1px solid rgba(255,255,255,0.08);
padding-top: 10px;
}
.prompt { color: #cdd6f4; white-space: nowrap; }
#input {
flex: 1;
background: transparent;
border: none;
outline: none;
color: #cdd6f4;
font-size: 14px;
font-family: monospace;
}
/* --- BOTTOM HELP LEGEND --- */
.footer-help {
background: #11151c;
border-top: 1px solid rgba(255, 255, 255, 0.05);
padding: 6px 12px;
font-size: 11px;
color: #585b70;
display: flex;
gap: 20px;
overflow-x: auto;
white-space: nowrap;
}
.footer-help span strong {
color: #cdd6f4;
}
</style>
</head>
<body data-webtui-theme="catppuccin-mocha">
<!-- Block Character Filled ASCII Header -->
<div class="banner-header">
<pre class="ascii-title">
ββββββ βββββββ ββββββββββββ ββββββββββ βββββββββββ βββ βββββββ βββββββ βββββββ βββββββ βββ βββββββ
βββββββββββββββββββββββββββββ βββββββββββββββββββββββ βββ βββββββββββββββββββββββββββββββββ βββββββββββ
ββββββββββββββββ βββ βββββββ βββ βββββββββ βββ βββ βββ βββ ββββββ ββββββββββββ ββββββ ββββ
ββββββββββββββββ βββ βββββ βββ βββββββββ ββββ ββββ βββ βββ ββββββ βββββββββββββββββββ βββ
βββ ββββββ βββ βββ βββ ββββββββββββββββ βββββββ βββββββββββββββββββββββββββββββ βββββββββββββββ
βββ ββββββ βββ βββ βββ βββββββ ββββββββ βββββ βββββββ βββββββ βββββββ ββββββ βββββ βββββββ </pre>
<div class="sub-tagline">Local Agent Orchestration Terminal β’ Core Runtime: Qwen2.5 + Dynamic Toolkits</div>
</div>
<!-- Multiplexer Navigation Bar -->
<div class="session-bar" id="sessionBar"></div>
<!-- Primary Interface Window -->
<div class="terminal">
<div id="log"></div>
<div class="input-row">
<span class="prompt" id="terminalPrompt">user@qwen:[~]~$</span>
<input id="input" autocomplete="off" autofocus placeholder="Type a message or /command..." />
</div>
</div>
<!-- Footer Keyboard Legend -->
<div class="footer-help">
<span><strong>Double-Click Tab</strong> Rename</span>
<span><strong>Hover + [x]</strong> Delete single</span>
<span><strong>/model [name]</strong> Switch core model</span>
<span><strong>[Wipe All]</strong> Factory reset data</span>
<span><strong>/new [name]</strong> Create context</span>
<span><strong>/clear</strong> Clear view</span>
</div>
<script type="module">
import { get, set, del } from 'https://cdn.jsdelivr.net/npm/idb-keyval@6/+esm';
const log = document.getElementById("log");
const input = document.getElementById("input");
const sessionBar = document.getElementById("sessionBar");
const terminalPrompt = document.getElementById("terminalPrompt");
const OLLAMA_URL = "http://localhost:11434/api/chat";
const REGISTRY_KEY = "multiplexer_registry_config";
const SESSION_PREFIX = "multiplexer_session_";
// List of available target models on your Ollama layer
const POPULAR_MODELS = [
"qwen2.5:7b",
"qwen2.5:14b",
"qwen2.5:latest",
"llama3.1:latest",
"mistral:latest",
"phi3:latest"
];
/* ---------------------------
MEMORY SYSTEM STRUCTURES
----------------------------*/
const SYSTEM_PROMPT = {
role: "system",
content: `You are a tool-using assistant.
When you need to use a tool to look up information or perform calculations, you MUST respond ONLY with a raw valid JSON object matching this schema:
{
"tool": "tool_name",
"arguments": { "key": "value" }
}
Do not include conversational text when calling a tool.
Otherwise, respond normally to the user in plain text.
Available tools:
- get_time: Returns the current date and time. No arguments needed.
- calc: Calculates a mathematical expression. Requires argument "expression" (string).`
};
let registry = {
currentActiveId: null,
activeModel: "qwen2.5:7b", // Default fallback model
list: []
};
let activeMessages = [SYSTEM_PROMPT];
let fullPersistentHistory = [];
/* ---------------------------
CONTEXT PRUNING (Sliding Window)
----------------------------*/
function pruneActiveMemory() {
const systemPrompt = activeMessages[0];
let chatHistory = activeMessages.slice(1);
const MAX_ACTIVE_ITEMS = 14;
if (chatHistory.length > MAX_ACTIVE_ITEMS) {
chatHistory = chatHistory.slice(chatHistory.length - MAX_ACTIVE_ITEMS);
if (chatHistory[0].role === "user" && chatHistory[0].content.startsWith("TOOL RESULT")) {
chatHistory.shift();
}
}
activeMessages = [systemPrompt, ...chatHistory];
}
/* ---------------------------
PERSISTENCE LAYER (IndexedDB)
----------------------------*/
async function saveAllToBrowser() {
try {
await set(REGISTRY_KEY, registry);
if (registry.currentActiveId) {
await set(SESSION_PREFIX + registry.currentActiveId, fullPersistentHistory);
}
} catch (err) {
console.error("Storage save operation encountered errors:", err);
}
}
async function loadSessionData(sessionId) {
try {
const savedData = await get(SESSION_PREFIX + sessionId);
fullPersistentHistory = savedData || [];
activeMessages = [SYSTEM_PROMPT, ...fullPersistentHistory.filter(m => !m.isToolActivityLog)];
pruneActiveMemory();
renderTerminalScreen();
renderTopMultiplexerBar();
} catch (err) {
print("Database retrieval block failure: " + err.message, "err");
}
}
/* ---------------------------
UI RENDERING MANAGERS
----------------------------*/
function renderTopMultiplexerBar() {
sessionBar.innerHTML = "";
registry.list.forEach((session, index) => {
const wrapper = document.createElement("div");
wrapper.className = "session-wrapper";
const tab = document.createElement("span");
const isActive = session.id === registry.currentActiveId;
tab.className = `session-tab ${isActive ? 'active' : ''}`;
tab.textContent = `${index}: ${session.name}`;
tab.addEventListener("click", (e) => {
if (!isActive && tab.tagName === 'SPAN') switchSession(index);
});
tab.addEventListener("dblclick", (e) => {
e.stopPropagation();
const editorInput = document.createElement("input");
editorInput.type = "text";
editorInput.className = "rename-input";
editorInput.value = session.name;
const finishRename = async () => {
const freshName = editorInput.value.trim();
if (freshName && freshName !== session.name) {
session.name = freshName;
await saveAllToBrowser();
renderTerminalScreen();
}
renderTopMultiplexerBar();
};
editorInput.addEventListener("keydown", (ke) => {
if (ke.key === "Enter") finishRename();
if (ke.key === "Escape") renderTopMultiplexerBar();
});
editorInput.addEventListener("blur", finishRename);
wrapper.replaceChild(editorInput, tab);
editorInput.focus();
editorInput.select();
});
wrapper.appendChild(tab);
const delBtn = document.createElement("span");
delBtn.className = "delete-btn";
delBtn.textContent = "[x]";
delBtn.title = "Delete Session";
delBtn.addEventListener("click", (e) => {
e.stopPropagation();
handleDeleteSessionConfirmation(index);
});
wrapper.appendChild(delBtn);
sessionBar.appendChild(wrapper);
});
const actionsGroup = document.createElement("div");
actionsGroup.className = "bar-actions-group";
// Unintrusive Model Selection Element
const modelWrapper = document.createElement("div");
modelWrapper.className = "model-selector-wrapper";
modelWrapper.innerHTML = `<span>model:</span>`;
const modelSelect = document.createElement("select");
modelSelect.className = "model-select-native";
// Make sure the active model is always in the list options
const modelsToRender = [...new Set([registry.activeModel, ...POPULAR_MODELS])];
modelsToRender.forEach(modelName => {
const opt = document.createElement("option");
opt.value = modelName;
opt.textContent = modelName;
if (modelName === registry.activeModel) opt.selected = true;
modelSelect.appendChild(opt);
});
modelSelect.addEventListener("change", async (e) => {
await switchActiveModel(e.target.value);
});
modelWrapper.appendChild(modelSelect);
actionsGroup.appendChild(modelWrapper);
const createBtn = document.createElement("span");
createBtn.className = "new-session-btn";
createBtn.textContent = "+ [New]";
createBtn.addEventListener("click", () => handleCreateSession());
actionsGroup.appendChild(createBtn);
const wipeBtn = document.createElement("span");
wipeBtn.className = "wipe-workspace-btn";
wipeBtn.textContent = "[Wipe All]";
wipeBtn.title = "Irreversibly delete all database history records";
wipeBtn.addEventListener("click", () => handleWipeAllSessionsConfirmation());
actionsGroup.appendChild(wipeBtn);
sessionBar.appendChild(actionsGroup);
}
function renderTerminalScreen() {
log.innerHTML = "";
const currentSession = registry.list.find(s => s.id === registry.currentActiveId);
const sessionName = currentSession ? currentSession.name : "none";
terminalPrompt.textContent = `user@qwen:[${sessionName}]~$`;
if (!currentSession) {
print("No active environment available. Please click '+ [New]' or type /new.", "sys");
return;
}
if (fullPersistentHistory.length === 0) {
print(`Welcome to session [${sessionName}]. Current Core: ${registry.activeModel}. Type your message or run /help.`, "sys");
return;
}
for (const msg of fullPersistentHistory) {
if (msg.role === "user" && !msg.content.startsWith("TOOL RESULT")) {
print(`user@qwen:[${sessionName}]~$ ${msg.content}`, "user");
} else if (msg.role === "assistant") {
if (!msg.content.trim().startsWith("{")) {
print(msg.content, "ai");
}
} else if (msg.role === "system" && msg.isToolActivityLog) {
print(msg.content, "tool");
}
}
}
function print(text, cls="sys") {
const div = document.createElement("div");
div.className = "line " + cls;
div.textContent = text;
log.appendChild(div);
log.scrollTop = log.scrollHeight;
return div;
}
/* ---------------------------
MULTIPLEXER OPERATIONS
----------------------------*/
async function switchActiveModel(newModelName) {
if (!newModelName || !newModelName.trim()) return;
registry.activeModel = newModelName.trim();
await saveAllToBrowser();
print(`Engine target processing runtime hot-swapped to: ${registry.activeModel}`, "sys");
renderTopMultiplexerBar();
}
async function handleCreateSession(customName = null) {
const id = "s_" + Date.now();
const name = customName ? customName.trim() : `session-${registry.list.length}`;
registry.list.push({ id, name });
registry.currentActiveId = id;
fullPersistentHistory = [];
activeMessages = [SYSTEM_PROMPT];
await saveAllToBrowser();
renderTopMultiplexerBar();
renderTerminalScreen();
}
async function switchSession(index) {
const target = registry.list[index];
if (!target) {
print(`Error: Session index context [${index}] not tracked inside current workspace registry profiles.`, "err");
return;
}
registry.currentActiveId = target.id;
await saveAllToBrowser();
await loadSessionData(target.id);
}
async function handleDeleteSessionConfirmation(index) {
const targetSession = registry.list[index];
if (!targetSession) return;
if (confirm(`Are you sure you want to permanently delete session "${targetSession.name}"?`)) {
await del(SESSION_PREFIX + targetSession.id);
registry.list.splice(index, 1);
if (registry.currentActiveId === targetSession.id) {
if (registry.list.length > 0) {
const nextIndexFallback = Math.max(0, index - 1);
registry.currentActiveId = registry.list[nextIndexFallback].id;
await set(REGISTRY_KEY, registry);
await loadSessionData(registry.currentActiveId);
} else {
registry.currentActiveId = null;
fullPersistentHistory = [];
activeMessages = [SYSTEM_PROMPT];
await set(REGISTRY_KEY, registry);
renderTopMultiplexerBar();
renderTerminalScreen();
}
} else {
await set(REGISTRY_KEY, registry);
renderTopMultiplexerBar();
}
print(`Successfully removed terminal workspace tracking profile target container: [${targetSession.name}]`, "sys");
}
}
async function handleWipeAllSessionsConfirmation() {
const explicitPromptText = "β οΈ WARNING: This will permanently delete ALL sessions and history logs. This action cannot be undone.\n\nType 'WIPE' to confirm initialization:";
const confirmationInput = prompt(explicitPromptText);
if (confirmationInput === "WIPE") {
print("Initiating full environment memory database purge...", "err");
for (const session of registry.list) {
await del(SESSION_PREFIX + session.id);
}
await del(REGISTRY_KEY);
registry.list = [];
registry.currentActiveId = null;
registry.activeModel = "qwen2.5:7b";
fullPersistentHistory = [];
activeMessages = [SYSTEM_PROMPT];
print("Database scrub complete. Re-initializing factory general configuration environments.", "sys");
await handleCreateSession("general");
} else {
print("Workspace wipe sequence aborted by user action.", "sys");
}
}
/* ---------------------------
SLASH COMMAND INTERCEPTOR
----------------------------*/
async function handleSlashCommand(rawInput) {
const parts = rawInput.trim().split(" ");
const cmd = parts[0].toLowerCase();
const args = parts.slice(1).join(" ");
print(`user@qwen:[command]~$ ${rawInput}`, "user");
switch (cmd) {
case "/new":
await handleCreateSession(args || null);
break;
case "/model":
if (!args.trim()) {
print(`Current active context orchestration engine model target: ${registry.activeModel}`, "sys");
print(`Usage option: /model [ollama-model-tag] (e.g., /model llama3.1:latest)`, "sys");
} else {
await switchActiveModel(args);
}
break;
case "/switch":
const targetIndex = parseInt(args, 10);
if (isNaN(targetIndex)) {
print("Usage error syntax structural rule: /switch [numerical-index-id]", "err");
} else {
await switchSession(targetIndex);
}
break;
case "/rename":
if (!args.trim()) {
print("Usage error syntax: /rename [new-session-tag-name]", "err");
} else {
const activeItem = registry.list.find(s => s.id === registry.currentActiveId);
if (activeItem) {
activeItem.name = args.trim();
await saveAllToBrowser();
renderTopMultiplexerBar();
renderTerminalScreen();
}
}
break;
case "/delete":
const delIdx = parseInt(args, 10);
if (isNaN(delIdx)) {
print("Usage error syntax: /delete [numerical-index-id]", "err");
} else {
await handleDeleteSessionConfirmation(delIdx);
}
break;
case "/wipeall":
await handleWipeAllSessionsConfirmation();
break;
case "/ls":
print("--- Active Workspace Environments ---", "sys");
registry.list.forEach((s, idx) => {
const activeMarker = s.id === registry.currentActiveId ? " (active)" : "";
print(` [${idx}]: ${s.name}${activeMarker}`, "sys");
});
break;
case "/clear":
log.innerHTML = "";
break;
case "/help":
print("Available workspace commands:", "sys");
print(" /model [tag] - Hot-swap core backend model parsing engine dynamically", "sys");
print(" /new [name] - Create a brand new independent conversation container", "sys");
print(" /switch [index] - Hot-swap active screen output to alternate target history", "sys");
print(" /rename [name] - Changes character pointer tracking tag assigned to window row", "sys");
print(" /delete [index] - Deletes and drops tracked IndexedDB context elements from storage", "sys");
print(" /wipeall - Destroys and cleans entire memory workspace databases", "sys");
print(" /ls - Lists out all tracking logs captured via IndexedDB system paths", "sys");
print(" /clear - Standard display layer terminal clear operation layout reset", "sys");
break;
default:
print(`Unrecognized multiplexer control sequence pipeline call target '${cmd}'. Try calling /help.`, "err");
}
}
/* ---------------------------
LOCAL ENVIRONMENT TOOLS
----------------------------*/
function runTool(name, args) {
if (name === "get_time") {
return { time: new Date().toISOString() };
}
if (name === "calc") {
try {
const evaluate = new Function(`return (${args.expression})`);
return { result: evaluate() };
} catch {
return { error: "invalid expression" };
}
}
return { error: "unknown tool" };
}
function tryParseTool(text) {
try {
const obj = JSON.parse(text.trim());
if (obj.tool && obj.arguments) return obj;
} catch {}
return null;
}
/* ---------------------------
STREAM INTERFACE DRIVER
----------------------------*/
async function streamAI(res) {
const div = print("", "ai");
const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
let fullText = "";
while (true) {
const { value, done } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop();
for (const line of lines) {
if (!line.trim()) continue;
try {
const json = JSON.parse(line);
const token = json.message?.content || "";
div.textContent += token;
fullText += token;
log.scrollTop = log.scrollHeight;
} catch {}
}
}
return fullText;
}
async function callModel() {
const res = await fetch(OLLAMA_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
model: registry.activeModel, // Dynamically injection based on selection config
stream: true,
messages: activeMessages
})
});
if (!res.ok || !res.body) throw new Error(`Ollama communication pipeline break during request using model ${registry.activeModel}`);
return res;
}
/* ---------------------------
AGENTIC EXECUTION RUNTIME ENGINE
----------------------------*/
async function askAI(prompt) {
const currentSession = registry.list.find(s => s.id === registry.currentActiveId);
const sessionLabel = currentSession ? currentSession.name : "~";
print(`user@qwen:[${sessionLabel}]~$ ${prompt}`, "user");
const userMsg = { role: "user", content: prompt };
activeMessages.push(userMsg);
fullPersistentHistory.push(userMsg);
let isAgentProcessing = true;
let executionDepthGuard = 5;
try {
while (isAgentProcessing && executionDepthGuard > 0) {
executionDepthGuard--;
const responseStream = await callModel();
const aiResponseText = await streamAI(responseStream);
const assistantMsg = { role: "assistant", content: aiResponseText };
activeMessages.push(assistantMsg);
fullPersistentHistory.push(assistantMsg);
const parsedToolRequest = tryParseTool(aiResponseText);
if (parsedToolRequest) {
const actionMessage = `π§ Executing tool: ${parsedToolRequest.tool}...`;
print(actionMessage, "tool");
fullPersistentHistory.push({ role: "system", content: actionMessage, isToolActivityLog: true });
const toolOutcome = runTool(parsedToolRequest.tool, parsedToolRequest.arguments);
const outcomeString = `π¦ Response: ${JSON.stringify(toolOutcome)}`;
print(outcomeString, "tool");
fullPersistentHistory.push({ role: "system", content: outcomeString, isToolActivityLog: true });
const toolResultFeedback = {
role: "user",
content: `TOOL RESULT for '${parsedToolRequest.tool}': ${JSON.stringify(toolOutcome)}`
};
activeMessages.push(toolResultFeedback);
fullPersistentHistory.push(toolResultFeedback);
} else {
isAgentProcessing = false;
}
}
await saveAllToBrowser();
pruneActiveMemory();
} catch (err) {
print("Error encountered inside tracking node loops: " + err.message, "err");
}
}
/* ---------------------------
DOM INTERFACES INTERCEPT
----------------------------*/
input.addEventListener("keydown", async (e) => {
if (e.key === "Enter") {
const value = input.value.trim();
if (!value) return;
input.value = "";
if (value.startsWith("/")) {
await handleSlashCommand(value);
} else {
if (!registry.currentActiveId) {
print("No active environment available. Please execute '/new' command to spawn a session first.", "err");
return;
}
await askAI(value);
}
}
});
/* ---------------------------
SYSTEM ENTRY BOOT STRAPPER
----------------------------*/
async function boot() {
try {
const savedRegistry = await get(REGISTRY_KEY);
if (savedRegistry && savedRegistry.list.length > 0) {
registry = savedRegistry;
// Ensure configuration object structure compatibility if updating from previous version
if (!registry.activeModel) registry.activeModel = "qwen2.5:7b";
renderTopMultiplexerBar();
await loadSessionData(registry.currentActiveId);
} else {
await handleCreateSession("general");
}
} catch (e) {
console.warn("Storage profile structure state clean initialization step required:", e);
await handleCreateSession("general");
}
}
boot();
</script>
</body>
</html>
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (1)
Nice, looks solid!