Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>FocusQuestNew to Visual Studio Code? Get it now.
FocusQuest

FocusQuest

Preview

focusquest

| (0) | Free
Gamified ADHD-friendly task + Pomodoro + local AI breakdown assistant (privacy-first).
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

FocusQuest Extension (Prototype Evolving to MVP)

FocusQuest Demo

Demo GIF generated locally (no external services).

Changelog · This is a preview build (0.1.x). See CHANGELOG for recent changes.

This extension/ folder now contains the evolving TypeScript implementation of FocusQuest: gamified task breakdown, XP + levels, badges, streaks, Pomodoro sessions, hierarchical epics, and optional local AI task generation via Ollama.

Privacy & Local-First Guarantee: FocusQuest makes no outbound network or telemetry calls. The only HTTP requests performed are to a user‑controlled local Ollama endpoint (default http://localhost:11434). If unreachable, a safe fallback task list is generated locally.

Run Locally (Dev)

  1. Open the repository in VS Code.
  2. Open this extension folder (or use a multi-root workspace).
  3. Install dependencies: npm install.
  4. Press F5 (Run Extension) to launch the Extension Development Host.
  5. Use the Command Palette (Ctrl+Shift+P) and try commands under the “FocusQuest:” prefix.

Build / test quick reference:

npm run build   # compile to dist/
npm test        # run mocha tests (TS + legacy JS test)

Key Features (Current Prototype)

Area Capabilities
Tasks / Quests Add, complete, hierarchical epics with progress auto-complete, AI-labeled subtasks
AI Breakdown Local LLM (Ollama) generates 3–7 focused subtasks (fallback if unreachable)
Gamification XP + level curve, multiple badges (first quest, focus sessions, streak tiers, AI usage, Pomodoro master, distraction slayer)
Streaks Daily focus session streak tracking with longest streak memory & new 5‑day badge
Pomodoro Start focus / break sessions, pause/resume, auto-switch focus→break, persistent restart after window reload
Dashboard Webview with live incremental updates (XP, streak, sessions, tasks, badges, last AI suggestion)
Status Bar XP summary, truncated last AI suggestion, live Pomodoro remaining time (updates persist across reload)
Persistence Unified immutable state store via VS Code globalState (Pomodoro session restored if still active)

Level formula: level = floor( (xp / 100) ** 0.8 ) (subject to tuning).

Commands

Note: The authoritative list of contributed commands lives in package.json. This table highlights the most common user-facing commands. | Command | Purpose | |---------|---------| | FocusQuest: Add Task | Create a new quest/task | | FocusQuest: Complete Quest | Mark a task done (awards XP) | | FocusQuest: Start Focus Session | Begin a focus Pomodoro (25m default) | | FocusQuest: Start Break | Begin break interval (5m default) | | FocusQuest: Open Dashboard | Show live progress dashboard | | FocusQuest: Break Down Task | Create a new epic + AI subtasks | | FocusQuest: Break Down This Task | Context-menu breakdown for existing task (adds children) | | FocusQuest: Check Ollama Status | Verifies local Ollama service & model availability | | FocusQuest: Convert Task to Epic | Turns a normal task into an epic so you can add subtasks (manual or AI) | | FocusQuest: Rename Task | Rename an existing quest/epic | | FocusQuest: Delete Task | Delete a task (and cascades its subtasks) | | FocusQuest: Pause Pomodoro | Pause the active focus/break timer (retains remaining time) | | FocusQuest: Resume Pomodoro | Resume a paused timer | | FocusQuest: Show Stats | Display tasks completed, focus sessions, streak info |

Context Menu: In the quest tree, right-click (or use inline menu) to break down an existing task when pending.

Local LLM (Ollama) Setup

FocusQuest performs all AI breakdowns locally. Install Ollama and pull a model (default: llama3). See ../docs/ollama-setup.md for detailed steps (Windows focused + cross-platform notes).

Quick start:

ollama pull llama3
ollama run llama3 "ping"

Then in VS Code run: FocusQuest: Check Ollama Status.

If Ollama is not reachable, breakdown commands still return a fallback list so you are never blocked.

Architecture Overview

Primary modules live under src/:

  • stateStore.ts – unified immutable persisted app state
  • questManager.ts – task CRUD and ordering
  • questTreeProvider.ts – hierarchical tree with epic progress labels
  • rewards.ts / badges.ts – XP curve & badge evaluation
  • streak.ts – date-based streak advancement
  • pomodoroTimer.ts – session events foundation
  • llm/LLMClient.ts – local Ollama integration + fallback
  • webview/DashboardPanel.ts – incremental UI updates via postMessage

Tests

Run all tests:

npm test

Current coverage includes rewards, badges (including AI & streak tiers), streak logic, state store immutability, hierarchy/epics, and AI badge logic.

Settings

You can customize AI usage and Pomodoro durations via VS Code Settings (File > Preferences > Settings) and searching for "FocusQuest":

Setting Description Default
focusquest.ai.enabled Toggle all AI breakdown features true
focusquest.ai.model Ollama model name used for breakdowns llama3
focusquest.ai.timeoutMs Legacy overall AI operation timeout (non-stream path) 10000
focusquest.ai.requestTimeoutMs Overall HTTP / idle stream timeout (resets per chunk) 20000
focusquest.ai.baseUrl Base URL for local Ollama server http://localhost:11434
focusquest.ai.streamingEnabled Stream incremental breakdown chunks true
focusquest.ai.streamChunkSize Max characters per streamed chunk 200
focusquest.ai.feedMaxChars Max characters stored per AI feed line 240
focusquest.ai.zeroTaskAutoRetry Silent retry when zero subtasks parsed true
focusquest.ai.collapseWhitespace Normalize whitespace in generated subtasks true
focusquest.experimentalBadges Enable extra (non-MVP) badge logic false
focusquest.motivation.enabled Enable idle/celebration motivational prompts true
focusquest.motivation.idleMinutes Minutes idle before nudge 90
focusquest.pomodoro.focusMinutes Focus session length (minutes) 25
focusquest.pomodoro.breakMinutes Break length (minutes) 5

Changing a setting hot-reloads the client & timer (you'll see a toast: "FocusQuest settings reloaded"). If AI is disabled, breakdown commands show a warning and abort.

AI Timeouts Explained

There are two relevant timeout layers now:

  1. focusquest.ai.requestTimeoutMs – Low-level HTTP/socket timeout. If the Ollama endpoint does not respond or stalls establishing a stream, the request aborts at this boundary (triggers a single automatic retry unless you cancelled).
  2. Streaming idle timeout (internal) – Instead of a hard wall clock, streaming breakdowns now reset an idle timer every time a chunk arrives. Only if no chunk arrives for the configured idle window (derived from ai.timeoutMs) will it abort. This prevents large model responses from being cut off prematurely.

If both the initial attempt and retry fail (non-abort), FocusQuest falls back to a generic 4‑step task list so you're never blocked.

Zero-Task UX & Metrics

If the model returns zero parseable subtasks (not a fallback), the feed line is annotated with (no subtasks parsed) and an informational toast offers a one-click "Regenerate with more detail" action that re-queues the breakdown with an appended guidance hint. These occurrences are counted in the ai.emptyBreakdowns metric (viewable via FocusQuest: Show AI Health). When focusquest.ai.zeroTaskAutoRetry is true, a silent second attempt is made first (with a light instruction suffix) before surfacing the UX prompt.

Roadmap (Short Term Ideas)

  • Drag-and-drop task reordering
  • Additional badge images & tooltips
  • Advanced epic analytics (velocity, completion pacing)
  • In-editor inline progress annotations

Contributing

See root CONTRIBUTING.md. Please open an issue before large changes. All contributions should keep AI calls local.


This is an iterative prototype: expect rapid refactors. Feedback & issue reports welcome.

Implementation Notes (Recent Enhancements)

  • Debounced tree refresh batching (50ms) minimizes UI churn when AI generates many subtasks at once.
  • Duplicate AI subtask prevention: repeated breakdown of the same task ignores case/whitespace duplicates.
  • Configurable whitespace normalization: set focusquest.ai.collapseWhitespace to false to preserve original spacing (may allow near-duplicates intentionally).
  • Duplicate AI subtask prevention with telemetry: skipped duplicates counted in ai.duplicatesSkipped (potential future "Refined Planner" badge hook).
  • Zero-yield feedback: if no unique subtasks are produced or the model yields zero tasks, feed marks (no subtasks parsed) and you get a rephrase prompt; counted in emptyBreakdowns.
  • New recovery badge (experimental): first_non_empty_after_empty awarded when you successfully generate a non-empty breakdown after at least one empty attempt.
  • QuestManager now uses immutable updates and throws a descriptive error if a frozen task sneaks into a mutation path (dev safety guard).
  • Pomodoro persistence: active session (including paused state) survives reload; status bar + dashboard stay in sync.

Events (Developer Reference)

FocusQuest uses a lightweight internal event bus to decouple controllers and UI surfaces. Common events:

Event Payload (simplified) Producer Notes
taskUpdated { taskId } QuestManager Any CRUD affecting a task/epic.
rewardsUpdated { xp, level } Rewards XP / level change triggers status UI refresh.
badgesUpdated { newBadges[] } Badges Fired only when new badges unlocked.
pomodoroStateChanged { state } PomodoroTimer 'focus' 'break' 'idle' transitions.
pomodoroTick { remainingMs } PomodoroTimer Approx 1s cadence for timer display.
pomodoroPaused / pomodoroResumed {...} PomodoroTimer Pause/resume lifecycle.
streakChanged { currentDays, longest } Streak logic Streak progress for badges/UI.
aiBreakdownStarted { title, targetId, streaming } AIController NEW: deterministic hook emitted synchronously when a breakdown run begins (enables reliable cancellation tests + potential UI spinners).
aiBreakdownChunk { parentTitle, chunk, isFinal? } AIController Streamed textual fragments; isFinal marks summary/terminal chunk.
aiSuggestionReady { message, type } AIController Final AI summary (used for status bar + feed).
aiQueueDepthChanged { depth } AIController Queue size after enqueue / completion.
storageFlushed { timestamp } StateStore Emitted after atomic write for future metrics.

If you introduce a new event: (1) add it to types.ts, (2) document it here & in docs/architecture-modules.md, (3) add a focused test if it influences logic.

npm install

License

MIT – see repository root LICENSE.

Demo GIF Generation

If images/demo.gif did not load above, generate it locally:

npm run generate:gif

By default it searches ../docs/videos/ for FocusQuest_Sept_25.mp4 (or FocusQuest.mp4). To specify a file:

npm run generate:gif -- ../docs/videos/YourRecording.mp4

The script creates a palette for higher quality with fewer colors, outputs to extension/images/demo.gif (included in the published package).

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2025 Microsoft