Plan tools extended to all modes; recent chat sessions added to
Authenticated Home view; drone locking and chat session startup factored
out of Project Manager into Chat Session view and made universal; update
for AGENTS.md.
- README.md: Added gadget-tasks and @gadget/ai-toolbox to projects table,
added Scheduled Tasks architecture section with diagram, updated
monorepo structure, added gadget-tasks to dev server instructions,
added doc link
- docs/agent-toolbox.md: Updated to reflect @gadget/ai-toolbox extraction
from @gadget/ai. Changed IAiEnvironment → GadgetToolboxEnvironment,
AiTool → GadgetTool, updated import paths, config examples, and added
Tool Categories section. Clarified gadget-tasks is NOT a consumer.
- docs/gadget-tasks.md: New documentation covering architecture, per-task
execution flow, configuration, startup/shutdown sequences, concurrency,
work order tracking, heartbeat, error recovery, and getting started.
Converts gadget-tasks from a duplicated codebase with direct MongoDB access
to a headless IDE client that uses gadget-code's REST API and Socket.IO
protocol to submit and process task prompts through the existing pipeline.
Deleted (no longer needed):
- gadget-tasks/src/models/ (5 Mongoose models — duplicated from gadget-code)
- gadget-tasks/data/prompts/ (11 prompt templates — duplicated from gadget-code)
- gadget-tasks/src/services/executor.ts (629-line AWL loop — duplicated from gadget-drone)
- gadget-tasks/src/services/ai.ts (direct AI API calls — drones do this now)
- gadget-tasks/src/services/workspace.ts (workspace management — drones do this now)
Added:
- gadget-tasks/src/services/platform.ts — REST API + Socket.IO headless IDE client
with session lock, workspace mode, prompt submission, work order tracking
Rewritten:
- gadget-tasks/src/gadget-tasks.ts — new startup: user login → auth → drone
selection → Socket.IO connect → schedule tasks (no MongoDB)
- gadget-tasks/src/services/scheduler.ts — delegates to PlatformService.executeTask()
- gadget-tasks/src/config/env.ts — platform.baseUrl config, no mongodb/google
gadget-code changes:
- Added PATCH /api/v1/projects/:projectId/tasks/:taskId/lastRun route
- Added ProjectService.updateTaskLastRun() for atomic task field update
Config changes:
- GadgetTasksConfig: replaced mongodb with platform.baseUrl, removed google.cse
- Dependencies: removed mongoose, @gadget/ai, @gadget/ai-toolbox, dayjs,
simple-git, nanoid; added socket.io-client, @inquirer/prompts
- IChatSession/IChatTurn interfaces: add optional numCtx field
- Mongoose schemas: add numCtx field to ChatSession and ChatTurn
- API controller: validate numCtx (>=16384, multiple of 8192)
- ChatSessionService: persist numCtx on session, pass through to turn
- SessionPanel: add range slider for Context Window (hidden for OpenAI)
- Drone buildDroneModelConfig: prefer turn.numCtx over model defaults
Complete Phase 1 of subprocess management in gadget-drone:
- SubProcessService with graceful shutdown (SIGINT→SIGKILL), halt, getLog
- SubprocessTool with create/list/kill/killAll/halt/log commands
- Registered in agent toolbox for build/test/ship/develop modes
- Fixed missing {{process_management_block}} replacement in chat-session.ts
- 34 unit tests across service and tool
- Comprehensive documentation in docs/subprocess.md
Documents:
- Complete session history and what was accomplished
- ACE → CodeMirror migration rationale and steps
- Flex layout height constraint fix pattern
- Key technical learnings (CJS/ESM interop, flex layouts)
- Remaining steps organized by priority (high/medium/low)
- Continuation prompt template for next session
- MVP success criteria (all ✅ complete)
This serves as the handoff document for the next developer
or AI agent continuing work on User Mode.
Documents the complete ACE → CodeMirror migration, including:
- Root cause analysis of react-ace CJS/ESM incompatibility with Vite
- Migration steps and rationale for @uiw/react-codemirror
- Flex layout height constraint fix and the underlying pattern
- Key technical learnings about CJS/ESM interop and flex layouts
- Remaining steps and continuation prompt for next session
This serves as the authoritative reference for why we use CodeMirror
and how to properly constrain third-party components in flex layouts.
The editor was overflowing its container because @uiw/react-codemirror
renders a wrapper div that doesn't inherit flex constraints by default.
Fixed by adding CSS rules that:
1. Set overflow:hidden on .cm-editor-container
2. Target the wrapper div (> div) with flex:1, min-height:0, overflow:hidden
3. Set .cm-editor and .cm-scroller to overflow appropriately
This ensures the flex height constraint propagates through every level
of the CodeMirror DOM tree, and only .cm-scroller scrolls.
Layout chain:
.cm-editor-container (flex-1, min-h-0)
└─ wrapper div (flex:1, min-h-0, overflow:hidden)
└─ .cm-editor (flex:1, min-h-0, overflow:hidden)
└─ .cm-scroller (min-h-0, overflow:auto) ← only this scrolls
react-ace v14 is CommonJS-only with no ESM entry point, making it
fundamentally incompatible with Vite's ESM-first dev server. Every
CJS interop workaround failed. Switched to @uiw/react-codemirror v4.25
which ships proper dual ESM+CJS and works with Vite out of the box.
Changes:
- Remove ace-builds and react-ace dependencies
- Add @uiw/react-codemirror + 16 @codemirror/lang-* packages
- Add @uiw/codemirror-theme-tomorrow-night-blue (closest to ACE's 'tomorrow')
- Add @replit/codemirror-lang-csharp for C# support
- Rewrite EditorPanel.tsx: delete 108 lines of ACE boilerplate
(?url imports, setModuleUrl, CJS interop hack), replace with
~30 lines of clean CodeMirror language extension setup
- Delete vite.d.ts (only needed for ACE ?url import types)
- Remove optimizeDeps.include from vite.config.ts (not needed for CM)
- Add CodeMirror flex layout CSS to index.css
Supported languages: JavaScript/JSX, TypeScript/TSX, Python, JSON,
HTML, CSS, Less, YAML, Markdown, SQL, Java, Go, Rust, C/C++, C#,
PHP, XML. Unsupported types fall back to plain text.
Verified: tsc clean, vite build passes, heartbeat worker intact.
react-ace v14 ships CommonJS only ('main': 'lib/index.js'). Vite's dev
server pre-bundling wraps CJS modules as namespace objects where the
default export is nested under .default. This caused 'Element type is
invalid: got object' because import Ace from 'react-ace' resolved to
the module namespace instead of the React component.
Fix: import * as ReactAceModule and extract default with fallback:
const Ace = ReactAceModule.default || ReactAceModule
Same treatment for ace-builds import. Production build (Rolldown) was
unaffected due to different CJS interop handling.
- Added react-ace and ace-builds to optimizeDeps.include
- This forces Vite to properly bundle the CommonJS react-ace module
- Resolves 'Element type is invalid' error when opening files
The react-ace package uses CommonJS exports, and Vite needs to
pre-bundle it to properly handle the default export in ESM context.
- Fixed Ace import (default import, not named)
- Moved EditorPanel from FilesPanel to ChatSessionView
- Editor now replaces chat view when file is selected (per UI design guide)
- FILES panel now contains only the file tree
- Added editorFilePath state to track open file
- File selection in tree opens editor in content area
- Close button returns to chat view
This matches the UI design guide specification where the File Editor
replaces the Chat View in the content area when a file is selected.
Root Cause: CSS flex items default to min-height: auto, which prevents
flex-1 elements from shrinking below their content size. This caused
the FilesPanel to grow beyond its allocated space when the file tree
had many entries, pushing content off-screen.
Changes:
- FilesPanel.tsx: Added min-h-0 to root div to override min-height: auto
This allows flex-1 to actually constrain height and enable scrolling
- FileTree.tsx: Removed redundant overflow-auto and h-full from root div
The parent (FilesPanel flex-1 overflow-auto) already handles scrolling.
Nested scroll containers create height resolution issues.
The sidebar layout is now a clean single-scroll-container hierarchy:
Sidebar (flex flex-col, no overflow)
↳ SESSION (shrink-0, natural height)
↳ PROJECT (shrink-0, natural height)
↳ FilesPanel (flex-1 min-h-0) — constrained to available space
↳ Header (natural height)
↳ Scroll area (flex-1 overflow-auto) — THE scroll container
↳ FileTree (p-2 only) — no overflow, no h-full
↳ Footer (natural height)
- SESSION and PROJECT panels now have shrink-0 to prevent them from
growing unbounded and pushing FILES panel off-screen
- FILES panel with flex-1 now properly fills remaining vertical space
- File tree scrolls in-place while SESSION/PROJECT stay fixed