anycoder-dfe53256 / index.html
d310h's picture
Upload folder using huggingface_hub
aa814a5 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KaizenGO AI - Ollama Powered Task Coach</title>
<!-- Font Awesome for Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--bg-color: #1E1E1E;
--text-color: #E0E0E0;
--ai-color: #569CD6;
--done-color: #6A9955;
--button-bg: #2D2D30;
--accent-color: #007ACC;
--input-bg: #3C3C3C;
--list-bg: #252526;
--border-color: #3E3E42;
--font-main: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
--font-code: 'Consolas', 'Courier New', monospace;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
font-family: var(--font-main);
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* Header */
header {
background-color: #252526;
padding: 15px 20px;
border-bottom: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
align-items: center;
}
h1 {
font-size: 1.2rem;
color: var(--accent-color);
font-weight: 600;
display: flex;
align-items: center;
gap: 10px;
}
.status-bar {
display: flex;
gap: 15px;
font-size: 0.85rem;
}
.status-item {
display: flex;
align-items: center;
gap: 6px;
}
.status-active { color: #4CAF50; }
.status-offline { color: #FF5252; }
.status-checking { color: #FFC107; }
.anycoder-link {
font-size: 0.75rem;
color: #858585;
text-decoration: none;
opacity: 0.8;
}
.anycoder-link:hover { opacity: 1; color: var(--accent-color); }
/* Main Layout */
.container {
display: flex;
flex: 1;
overflow: hidden;
}
/* Sidebar (Task List) */
.sidebar {
width: 320px;
background-color: var(--bg-color);
border-right: 1px solid var(--border-color);
display: flex;
flex-direction: column;
padding: 10px;
flex-shrink: 0;
}
.section-title {
font-size: 1.1rem;
color: var(--accent-color);
margin-bottom: 10px;
font-weight: 600;
display: flex;
align-items: center;
gap: 8px;
}
.stats-bar {
font-size: 0.8rem;
color: #858585;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid var(--border-color);
}
.task-list-container {
flex: 1;
background-color: var(--list-bg);
border-radius: 4px;
overflow-y: auto;
padding: 5px;
margin-bottom: 15px;
border: 1px solid var(--border-color);
}
.task-item {
padding: 10px;
margin-bottom: 5px;
background-color: var(--button-bg);
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
border-left: 3px solid transparent;
}
.task-item:hover {
background-color: #3a3a3c;
}
.task-item.selected {
border-left: 3px solid var(--accent-color);
background-color: #2D2D30;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
}
.task-item.done {
opacity: 0.6;
text-decoration: line-through;
border-left-color: var(--done-color);
}
.task-title {
font-size: 0.95rem;
font-weight: 500;
}
.task-meta {
font-size: 0.75rem;
color: #999;
margin-top: 4px;
display: flex;
gap: 10px;
}
/* Quick Actions */
.quick-actions {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
margin-bottom: 15px;
}
.action-btn {
padding: 8px;
background-color: var(--button-bg);
color: var(--text-color);
border: 1px solid var(--border-color);
border-radius: 4px;
cursor: pointer;
font-size: 0.85rem;
transition: background 0.2s;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
}
.action-btn:hover {
background-color: #3E3E42;
border-color: var(--accent-color);
}
/* Task Management Buttons */
.task-controls {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 5px;
margin-bottom: 15px;
}
.control-btn {
padding: 6px;
background-color: var(--button-bg);
color: var(--text-color);
border: 1px solid var(--border-color);
border-radius: 3px;
cursor: pointer;
font-size: 0.8rem;
}
.control-btn:hover {
background-color: #3E3E42;
}
/* Main Chat Area */
.main-area {
flex: 1;
display: flex;
flex-direction: column;
padding: 20px;
overflow: hidden;
background-color: var(--bg-color);
}
.chat-header {
margin-bottom: 15px;
display: flex;
justify-content: space-between;
align-items: center;
}
.chat-display {
flex: 1;
background-color: var(--list-bg);
border-radius: 8px;
padding: 20px;
overflow-y: auto;
margin-bottom: 20px;
border: 1px solid var(--border-color);
font-family: var(--font-code);
font-size: 0.95rem;
line-height: 1.5;
box-shadow: inset 0 0 10px rgba(0,0,0,0.5);
}
.message {
margin-bottom: 15px;
padding: 10px 15px;
border-radius: 8px;
max-width: 90%;
animation: fadeIn 0.3s ease;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(5px); }
to { opacity: 1; transform: translateY(0); }
}
.msg-ai {
background-color: #252526;
border-left: 4px solid var(--ai-color);
align-self: flex-start;
}
.msg-system {
background-color: #2D2D30;
color: #ccc;
font-style: italic;
font-size: 0.85rem;
align-self: center;
text-align: center;
max-width: 100%;
border-radius: 20px;
width: fit-content;
}
.msg-user {
background-color: var(--accent-color);
color: white;
align-self: flex-end;
margin-left: auto;
border-radius: 8px 8px 0 8px;
}
.msg-steps {
background-color: #1a2e1a;
border-left: 4px solid var(--done-color);
color: #b8e0b8;
font-family: var(--font-code);
}
.chat-input-area {
display: flex;
gap: 10px;
background-color: var(--button-bg);
padding: 10px;
border-radius: 8px;
border: 1px solid var(--border-color);
}
.chat-input {
flex: 1;
background-color: var(--input-bg);
color: var(--text-color);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 10px;
font-family: var(--font-main);
font-size: 1rem;
outline: none;
}
.chat-input:focus {
border-color: var(--accent-color);
}
.send-btn {
background-color: var(--accent-color);
color: white;
border: none;
border-radius: 4px;
padding: 0 20px;
cursor: pointer;
font-weight: 600;
transition: background 0.2s;
}
.send-btn:hover {
background-color: #0062a3;
}
/* Settings Row */
.settings-row {
margin-top: 15px;
display: flex;
gap: 10px;
align-items: center;
flex-wrap: wrap;
}
.setting-item {
display: flex;
align-items: center;
gap: 8px;
background-color: var(--button-bg);
padding: 5px 10px;
border-radius: 4px;
border: 1px solid var(--border-color);
}
select, input[type="text"] {
background-color: var(--input-bg);
color: var(--text-color);
border: none;
padding: 5px;
border-radius: 3px;
font-family: var(--font-main);
}
.search-btn {
background-color: var(--accent-color);
color: white;
border: none;
padding: 5px 10px;
border-radius: 3px;
cursor: pointer;
}
.tool-btn {
background-color: var(--button-bg);
color: var(--text-color);
border: 1px solid var(--border-color);
padding: 5px 10px;
border-radius: 3px;
cursor: pointer;
}
.tool-btn:hover {
background-color: #3E3E42;
}
/* Responsive */
@media (max-width: 768px) {
.container {
flex-direction: column;
}
.sidebar {
width: 100%;
height: 30%;
border-right: none;
border-bottom: 1px solid var(--border-color);
}
.main-area {
height: 70%;
}
.task-controls {
grid-template-columns: 1fr 1fr;
}
.control-btn:last-child {
grid-column: span 2;
}
}
</style>
</head>
<body>
<header>
<h1><i class="fa-solid fa-robot"></i> KaizenGO AI <span style="font-size: 0.8em; opacity: 0.7;">- Ollama Powered</span></h1>
<div class="status-bar">
<div class="status-item" id="ollamaStatus">
<i class="fa-solid fa-wifi"></i> <span id="statusText">Checking...</span>
</div>
<div class="status-item">
<i class="fa-solid fa-list"></i> <span id="totalTasksDisplay">0 Tasks</span>
</div>
</div>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link" target="_blank">
Built with anycoder
</a>
</header>
<div class="container">
<!-- Sidebar -->
<aside class="sidebar">
<div class="section-title"><i class="fa-solid fa-clipboard-list"></i> Your Tasks</div>
<div class="stats-bar" id="taskStats">
Total: 0 | Pending: 0 | Done: 0
</div>
<div class="task-list-container" id="taskList">
<!-- Tasks will be injected here -->
<div style="text-align: center; color: #555; margin-top: 20px; font-style: italic;">
No tasks yet.<br>Click "New Task" to start.
</div>
</div>
<div class="section-title" style="font-size: 1rem; margin-top: 10px;"><i class="fa-solid fa-bolt"></i> Quick Actions</div>
<div class="quick-actions">
<button class="action-btn" onclick="app.startTaskCreation()">
<i class="fa-solid fa-plus"></i> New Task
</button>
<button class="action-btn" onclick="app.startDailyCheckin()">
<i class="fa-solid fa-sun"></i> Daily Check-in
</button>
</div>
<div class="section-title" style="font-size: 1rem; margin-top: 10px;"><i class="fa-solid fa-gear"></i> Task Controls</div>
<div class="task-controls">
<button class="control-btn" onclick="app.analyzeSelected()"><i class="fa-solid fa-magnifying-glass"></i> Analyze</button>
<button class="control-btn" onclick="app.toggleDone()"><i class="fa-solid fa-check-circle"></i> Done</button>
<button class="control-btn" onclick="app.editTask()"><i class="fa-solid fa-pen-to-square"></i> Edit</button>
<button class="control-btn" onclick="app.deleteTask()"><i class="fa-solid fa-trash"></i> Delete</button>
<button class="control-btn" onclick="app.viewSteps()"><i class="fa-solid fa-list-ol"></i> Steps</button>
<button class="control-btn" onclick="app.exportTasks()"><i class="fa-solid fa-file-arrow-down"></i> Export</button>
</div>
<div style="margin-top: auto; padding-top: 15px; border-top: 1px solid var(--border-color);">
<button class="action-btn" style="width: 100%; justify-content: center;" onclick="app.testOllama()">
<i class="fa-solid fa-wrench"></i> Test AI Connection
</button>
</div>
</aside>
<!-- Main Chat Area -->
<main class="main-area">
<div class="chat-header">
<div>
<div class="section-title" style="margin:0;"><i class="fa-solid fa-comments"></i> AI Assistant</div>
<div style="font-size: 0.8rem; color: #858585;">Powered by Ollama (Simulated Model: exaone3.5:2.4b)</div>
</div>
<button class="tool-btn" onclick="app.clearChat()"><i class="fa-solid fa-rotate-right"></i> Clear Chat</button>
</div>
<div class="chat-display" id="chatDisplay">
<!-- Chat history goes here -->
</div>
<div class="chat-input-area">
<input type="text" id="chatInput" class="chat-input" placeholder="Type your message here..." autocomplete="off">
<button class="send-btn" onclick="app.processUserResponse()">
<i class="fa-solid fa-paper-plane"></i> Send
</button>
</div>
<div class="settings-row">
<div class="setting-item">
<label>Font Size:</label>
<select id="fontSizeSelector" onchange="app.changeFontSize(this.value)">
<option value="10">10</option>
<option value="12" selected>12</option>
<option value="14">14</option>
<option value="16">16</option>
</select>
</div>
<div class="setting-item" style="flex-direction: row;">
<i class="fa-solid fa-search"></i>
<input type="text" id="searchInput" placeholder="Filter tasks..." oninput="app.searchTasks(this.value)">
<button class="search-btn" onclick="app.searchTasks(document.getElementById('searchInput').value)">Filter</button>
<button class="tool-btn" onclick="app.resetSearch()"><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="setting-item">
<button class="tool-btn" onclick="app.showHelp()"><i class="fa-solid fa-circle-question"></i> Help</button>
<button class="tool-btn" onclick="app.showSettings()"><i class="fa-solid fa-sliders"></i> Settings</button>
</div>
</div>
</main>
</div>
<script>
// --- Application Logic ---
class KaizenGOApp {
constructor() {
this.tasks = [];
this.config = {
fontSize: 12,
ollamaUrl: "http://localhost:11434/api/generate",
ollamaModel: "exaone3.5:2.4b"
};
this.conversation = {
mode: '', // '', 'task_creation', 'task_breakdown', 'daily_checkin'
step: 0,
context: {},
answers: []
};
this.selectedTaskId = null;
// Initialize
this.init();
}
init() {
this.loadFromStorage();
this.renderTasks();
this.updateStats();
this.addSystemMessage("Welcome to KaizenGO AI! I'm ready to help you organize your tasks.");
this.addSystemMessage("Click 'New Task' to start a guided conversation with the AI.");
// Setup Enter key for chat
document.getElementById('chatInput').addEventListener('keypress', (e) => {
if (e.key === 'Enter') this.processUserResponse();
});
}
// --- Storage Management ---
loadFromStorage() {
const storedTasks = localStorage.getItem('kaizenTasks');
const storedConfig = localStorage.getItem('kaizenConfig');
if (storedTasks) this.tasks = JSON.parse(storedTasks);
if (storedConfig) this.config = { ...this.config, ...JSON.parse(storedConfig) };
// Apply font
document.getElementById('fontSizeSelector').value = this.config.fontSize;
this.changeFontSize(this.config.fontSize);
}
saveToStorage() {
localStorage.setItem('kaizenTasks', JSON.stringify(this.tasks));
localStorage.setItem('kaizenConfig', JSON.stringify(this.config));
}
// --- Task Management ---
renderTasks(filterText = "") {
const listContainer = document.getElementById('taskList');
listContainer.innerHTML = '';
let filteredTasks = this.tasks;
if (filterText) {
filteredTasks = this.tasks.filter(t => t.title.toLowerCase().includes(filterText.toLowerCase()));
}
if (filteredTasks.length === 0) {
listContainer.innerHTML = '<div style="text-align: center; color: #555; margin-top: 20px; font-style: italic;">No tasks found.</div>';
} else {
filteredTasks.forEach(task => {
const taskEl = document.createElement('div');
taskEl.className = `task-item ${task.done ? 'done' : ''} ${this.selectedTaskId === task.id ? 'selected' : ''}`;
taskEl.onclick = () => this.selectTask(task.id);
taskEl.innerHTML = `
<div class="task-title">${task.title} ${task.done ? '<i class="fa-solid fa-check" style="float:right; color:var(--done-color)"></i>' : ''}</div>
<div class="task-meta">
<span>${task.done ? 'Completed' : 'Pending'}</span>
<span>${task.created}</span>
</div>
`;
listContainer.appendChild(taskEl);
});
}
this.updateStats();
}
updateStats() {
const total = this.tasks.length;
const done = this.tasks.filter(t => t.done).length;
const pending = total - done;
document.getElementById('taskStats').innerText = `Total: ${total} | Pending: ${pending} | Done: ${done}`;
document.getElementById('totalTasksDisplay').innerText = `${total} Tasks`;
}
selectTask(id) {
this.selectedTaskId = id;
this.renderTasks(document.getElementById('searchInput').value);
}
getSelectedTask() {
return this.tasks.find(t => t.id === this.selectedTaskId);
}
generateId() {
return 'TASK_' + Math.floor(Math.random() * 100000).toString().padStart(5, '0');
}
addTask(title, details = {}) {
const newTask = {
id: this.generateId(),
title: title,
done: false,
created: new Date().toLocaleDateString(),
...details,
steps: details.steps || []
};
this.tasks.push(newTask);
this.saveToStorage();
this.renderTasks();
this.addSystemMessage(`✅ Task created: ${title}`);
}
deleteTask() {
if (!this.selectedTaskId) {
this.addSystemMessage("⚠️ Please select a task to delete.");
return;
}
if (confirm("Are you sure you want to delete this task?")) {
this.tasks = this.tasks.filter(t => t.id !== this.selectedTaskId);
this.selectedTaskId = null;
this.saveToStorage();
this.renderTasks();
this.addSystemMessage("Task deleted.");
}
}
editTask() {
const task = this.getSelectedTask();
if (!task) {
this.addSystemMessage("⚠️ Please select a task to edit.");
return;
}
const newTitle = prompt("Edit task title:", task.title);
if (newTitle && newTitle.trim() !== "") {
task.title = newTitle.trim();
this.saveToStorage();
this.renderTasks();
this.addSystemMessage("Task updated.");
}
}
toggleDone() {
const task = this.getSelectedTask();
if (!task) {
this.addSystemMessage("⚠️ Please select a task.");
return;
}
task.done = !task.done;
if (task.done) {
task.completed = new Date().toLocaleDateString();
this.addSystemMessage(`🎉 Task marked as done: ${task.title}`);
} else {
this.addSystemMessage(`🔄 Task reopened: ${task.title}`);
}
this.saveToStorage();
this.renderTasks();
}
exportTasks() {
if (this.tasks.length === 0) {
this.addSystemMessage("No tasks to export.");
return;
}
let content = "KAIZENG EXPORT\n\n";
this.tasks.forEach(t => {
content += `[${t.done ? 'DONE' : 'PENDING'}] ${t.title}\n`;
if (t.steps.length > 0) {
t.steps.forEach((s, i) => content += ` ${i+1}. ${s}\n`);
}
content += "\n";
});
const blob = new Blob([content], { type: 'text/plain' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'kaizeng_tasks.txt';
a.click();
window.URL.revokeObjectURL(url);
this.addSystemMessage("💾 Tasks exported successfully.");
}
searchTasks(filter) {
this.renderTasks(filter);
}
resetSearch() {
document.getElementById('searchInput').value = "";
this.renderTasks();
}
// --- Chat & AI Logic (Simulated) ---
addMessage(sender, text, type = 'text') {
const chatDisplay = document.getElementById('chatDisplay');
const msgDiv = document.createElement('div');
let senderClass = 'msg-system';
let senderIcon = 'ℹ️';
if (sender === 'AI') {
senderClass = 'msg-ai';
senderIcon = '🤖 AI:';
} else if (sender === 'You') {
senderClass = 'msg-user';
senderIcon = '👤 You:';
} else if (sender === 'Steps') {
senderClass = 'msg-steps';
senderIcon = '📋 Plan:';
}
// Format text (convert newlines to <br>)
const formattedText = text.replace(/\n/g, '<br>');
msgDiv.className = `message ${senderClass}`;
msgDiv.innerHTML = `<strong>${senderIcon}</strong> ${formattedText}`;
chatDisplay.appendChild(msgDiv);
chatDisplay.scrollTop = chatDisplay.scrollHeight;
}
addSystemMessage(text) {
this.addMessage('System', text);
}
clearChat() {
document.getElementById('chatDisplay').innerHTML = '';
this.conversation.mode = '';
this.conversation.step = 0;
this.conversation.answers = [];
this.addSystemMessage("Chat cleared. How can I help you?");
}
processUserResponse() {
const inputEl = document.getElementById('chatInput');
const message = inputEl.value.trim();
if (!message) return;
this.addMessage('You', message);
inputEl.value = '';
// Handle based on mode
if (this.conversation.mode === 'task_creation') {
this.handleTaskCreationFlow(message);
} else if (this.conversation.mode === 'task_breakdown') {
this.handleTaskBreakdownFlow(message);
} else if (this.conversation.mode === 'daily_checkin') {
this.handleDailyCheckinFlow(message);
} else {
this.handleGeneralChat(message);
}
}
// --- AI Conversation Flows (Simulating Ollama) ---
startTaskCreation() {
this.conversation.mode = 'task_creation';
this.conversation.step = 0;
this.conversation.answers = [];
this.conversation.context = {};
this.addSystemMessage("Starting New Task Creation Wizard...");
this.simulateAiThinking(() => {
this.conversation.step = 1;
this.addMessage('AI', "Hello! I'm here to help you create a clear, actionable task. 🌟\n\nWhat would you like to accomplish? Keep it friendly and specific.");
});
}
handleTaskCreationFlow(response) {
this.conversation.answers.push(response);
if (this.conversation.step === 1) {
this.simulateAiThinking(() => {
this.conversation.step = 2;
this.addMessage('AI', `Got it! You want to "${response}".\n\nWhy is this important to you right now? What will completing this enable or give you?`);
});
} else if (this.conversation.step === 2) {
this.simulateAiThinking(() => {
this.conversation.step = 3;
this.addMessage('AI', `That's a great motivation: "${response}".\n\nWhen would you like this completed? (e.g., By Friday, End of month)`);
});
} else if (this.conversation.step === 3) {
this.simulateAiThinking(() => {
this.conversation.step = 4;
this.addMessage('AI', `Deadline set: "${response}".\n\nWhat challenges or obstacles might make this difficult for you?`);
});
} else if (this.conversation.step === 4) {
this.simulateAiThinking(() => {
this.conversation.step = 5;
this.addMessage('AI', `Obstacles noted: "${response}".\n\nFinally, on a scale of 1-10, how clear are you on your FIRST step? (1=Unclear, 10=Crystal clear)`);
});
} else if (this.conversation.step === 5) {
this.simulateAiThinking(() => {
this.conversation.mode = '';
this.conversation.step = 0;
// Generate Final Task
const taskTitle = this.conversation.answers[0];
const taskWhy = this.conversation.answers[1];
const taskDeadline = this.conversation.answers[2];
const taskObstacles = this.conversation.answers[3];
const taskClarity = this.conversation.answers[4];
// Generate "AI" Steps
let steps = [];
if (parseInt(taskClarity) < 5) {
steps = [
"Research information related to the task",
"Break the main goal into smaller sub-goals",
"Identify resources needed",
"Draft a preliminary plan",
"Review and refine the plan"
];
} else {
steps = [
"Start with the most critical sub-task immediately",
"Gather any missing tools or resources",
"Execute Step 1 of the main plan",
"Review progress at the end of the day",
"Adjust plan based on initial results"
];
}
this.addTask(taskTitle, {
why: taskWhy,
deadline: taskDeadline,
obstacles: taskObstacles,
steps: steps
});
this.addMessage('AI', `🎉 Task Created Successfully! "${taskTitle}" is now in your list.\n\nI've generated a plan based on your inputs. Remember your "Why": ${taskWhy}.\n\nGood luck!`);
});
}
}
startDailyCheckin() {
this.conversation.mode = 'daily_checkin';
this.conversation.step = 0;
this.conversation.answers = [];
this.addSystemMessage("Starting Daily Check-in...");
this.simulateAiThinking(() => {
this.conversation.step = 1;
this.addMessage('AI', "Good morning! 👋\n\nHow are you feeling about your tasks today? Are you feeling:\n1. Energized\n2. Overwhelmed\n3. Unsure where to start\n4. Procrastinating");
});
}
handleDailyCheckinFlow(response) {
this.conversation.answers.push(response);
if (this.conversation.step === 1) {
this.simulateAiThinking(() => {
this.conversation.step = 2;
this.conversation.mode = '';
let guidance = "";
if (response.toLowerCase().includes("energized")) {
guidance = "That's fantastic! Use this energy to tackle the most challenging task on your list first.";
} else if (response.toLowerCase().includes("overwhelmed")) {
guidance = "Take a deep breath. Let's break down your biggest task into a 5-minute action step. What's the very first physical movement needed?";
} else if (response.toLowerCase().includes("unsure")) {
guidance = "It's okay. Let's look at your task list. Pick ONE task that takes less than 15 minutes. Completing small wins builds momentum.";
} else {
guidance = "We've all been there. Set a timer for 25 minutes (Pomodoro). Just focus on opening the file or logging in. Action precedes motivation.";
}
this.addMessage('AI', `I understand you're feeling "${response}".\n\n${guidance}`);
});
}
}
analyzeSelected() {
const task = this.getSelectedTask();
if (!task) {
this.addSystemMessage("⚠️ Please select a task to analyze.");
return;
}
this.conversation.mode = 'task_breakdown';
this.conversation.step = 0;
this.conversation.answers = [];
this.conversation.currentTaskId = task.id;
this.addSystemMessage(`Analyzing: "${task.title}"...`);
this.simulateAiThinking(() => {
this.conversation.step = 1;
this.addMessage('AI', `I see the task: "${task.title}".\n\nTo help you break this down, can you tell me WHY completing this task is important to you? What will it give you?`);
});
}
handleTaskBreakdownFlow(response) {
this.conversation.answers.push(response);
if (this.conversation.step === 1) {
this.simulateAiThinking(() => {
this.conversation.step = 2;
this.addMessage('AI', `Understood: "${response}".\n\nOkay, for the task "${this.tasks.find(t=>t.id === this.conversation.currentTaskId)?.title}", what are the 3-5 smallest chunks you can imagine? Don't worry about order yet.`);
});
} else if (this.conversation.step === 2) {
this.simulateAiThinking(() => {
this.conversation.step = 3;
this.addMessage('AI', `Chunks noted: "${response}".\n\nIf you had to do ONE of these chunks right now (next 2 hours), which one would it be?`);
});
} else if (this.conversation.step === 3) {
this.simulateAiThinking(() => {
this.conversation.mode = '';
this.conversation.step = 0;
const task = this.tasks.find(t => t.id === this.conversation.currentTaskId);
if (task) {
task.steps = [
`Start with: "${response}" (Quick Win)`,
"Gather resources needed for other chunks",
"Execute Chunk 2",
"Execute Chunk 3",
"Review and Integrate results"
];
this.saveToStorage();
this.renderTasks();
this.addMessage('AI', "✅ Action Plan Generated!\n\nI've updated your task with a step-by-step plan. Start with your 'Quick Win' to build momentum!");
this.viewSteps();
}
});
}
}
handleGeneralChat(message) {
this.simulateAiThinking(() => {
let response = "I'm here to help with task management! \n\nTry:\n• 'Create a new task'\n• 'Check my stats'\n• 'Help'\n• Analyze a selected task";
const lowerMsg = message.toLowerCase();
if (lowerMsg.includes("help")) {
response = "📖 HELP\n\nSETUP: If Ollama is offline, you can still use the app for basic task management.\n\nFEATURES:\n• 'New Task' - Guided AI creation\n• 'Analyze' - Deep dive into selected task\n• Chat - Ask for motivation or tips";
} else if (lowerMsg.includes("stats") || lowerMsg.includes("statistics")) {
const total = this.tasks.length;
const done = this.tasks.filter(t => t.done).length;
response = `📊 CURRENT STATUS\nTotal Tasks: ${total}\nCompleted: ${done}\nPending: ${total - done}`;
} else if (lowerMsg.includes("hello") || lowerMsg.includes("hi")) {
response = "Hello there! Ready to be productive today? ☀️";
}
this.addMessage('AI', response);
});
}
viewSteps() {
const task = this.getSelectedTask();
if (!task) {
this.addSystemMessage("⚠️ Please select a task to view steps.");
return;
}
if (!task.steps || task.steps.length === 0) {
this.addSystemMessage("No steps defined for this task. Try clicking 'Analyze' first!");
return;
}
let stepsText = `📋 Action Plan for: ${task.title}\n`;
if (task.why) stepsText += `🎯 Purpose: ${task.why}\n`;
stepsText += "\n";
task.steps.forEach((step, index) => {
stepsText += `${index + 1}. ${step}\n`;
});
this.addMessage('Steps', stepsText);
}
testOllamaConnection() {
this.addSystemMessage("Testing AI Connection...");
const statusEl = document.getElementById('ollamaStatus');
const statusText = document.getElementById('statusText');
statusEl.className = "status-item status-checking";
statusText.innerText = "Testing...";
setTimeout(() => {
// In a real app, this would be an API call.
// Here we simulate success because we are in a browser.
statusEl.className = "status-item status-active";
statusText.innerText = "Online (Simulated)";
this.addSystemMessage("✅ Connection Test Successful! (Simulated Mode)\n\n*Note: Real Ollama connection requires a backend server due to browser CORS policies.");
}, 1500);
}
changeFontSize(size) {
document.body.style.fontSize = `${size}px`;
this.config.fontSize = size;
this.saveToStorage();
}
showHelp() {
this.addMessage('AI', "📖 HELP\n\n1. New Task: Use the AI to guide you through creating a plan.\n2. Analyze: Deep dive into an existing task to break it down.\n3. Daily Check-in: Start your day with a focused mindset.\n4. Filter: Use the search bar to find tasks quickly.\n\nNeed more? Ask me 'Help' anytime!");
}
showSettings() {
const newUrl = prompt("Ollama API URL:", this.config.ollamaUrl);
if (newUrl) {
this.config.ollamaUrl = newUrl;
this.saveToStorage();
this.addSystemMessage("Settings saved.");
}
}
simulateAiThinking(callback) {
// Visual feedback
const input = document.getElementById('chatInput');
const originalPlaceholder = input.placeholder;
input.placeholder = "AI is thinking...";
input.disabled = true;
setTimeout(() => {
input.placeholder = originalPlaceholder;
input.disabled = false;
input.focus();
if (callback) callback();
}, 1000 + Math.random() * 500); // Random delay 1-1.5s
}
}
// Start the App
const app = new KaizenGOApp();
</script>
</body>
</html>