Merge branch 'develop' of git.digitaltelepresence.com:rob/gadget into develop

This commit is contained in:
Rob Colbert 2026-05-18 09:11:16 -04:00
commit 0437ca66d8
8 changed files with 478 additions and 267 deletions

273
CHANGE.md
View File

@ -6,48 +6,50 @@ This document tracks all significant changes to Gadget Code, organized by date.
## 2026-05-17 (Sunday)
**Subagent Context Management and Tooling Stability**
**Release Hardening, Subagent Improvements, and Workspace Intelligence**
Today's focus shifted towards improving subagent context management and stabilizing developmental tools, including a fix for the prompt editor.
The day focused on preparing the v1.0.1 release with a hardened release script, fixing subagent context management, adding prompt draft persistence, and implementing intelligent workspace startup that detects the workspace directory by walking up the file hierarchy.
### Changes:
- **Subagent**: Implemented improvements to subagent context management.
- **Development**: Fixed prompt editor functionality.
- **Documentation**: Added gadget-tasks architecture documentation and updated technical documentation (README, `agent-toolbox.md`).
- **Dependencies/Build**: Addressed installation and global link issues.
- **Release**: Added hardened release script with error handling and pre-flight checks.
- **Subagent**: Improved subagent context management for more reliable agent operations.
- **Chat Session**: Implemented prompt draft save/restore so in-progress prompts survive view changes.
- **Workspace**: Added intelligent startup — drone detects workspace by walking up directory hierarchy.
- **Agent Tools**: Updated plan tool with improved prompt language and behavior.
- **Prompt Editor**: Expanded prompt editor capabilities.
- **gadget-tasks**: Course correction — converted to headless IDE client architecture (no direct DB access).
- **Documentation**: Added gadget-tasks architecture documentation; updated README and agent-toolbox docs.
- **Build**: Fixed installation and global link issues.
- **Tests**: Updated code-session tests to match current API expectations.
---
## 2026-05-16 (Saturday)
**Gadget-Tasks Architecture Correction and AI Toolbox Refactor**
**AI Toolbox Extraction and Project Manager Upgrades**
This update covers major architectural changes to `gadget-tasks` transition to a headless IDE client and the reorganization of the AI toolbox structure.
Completed the refactor extracting the AI toolbox from `@gadget/ai` into `@gadget/ai-toolbox`, and implemented Project Manager upgrades across Phases 14. Cleaned up incorrect dependencies.
### Changes:
- **Architecture**: Converted `gadget-tasks` from directly accessing MongoDB to a headless IDE client architecture using REST API and Socket.IO.
- **Infrastructure**: Added `platform.ts` (headless IDE client with session lock and workspace mode) to `gadget-tasks`.
- **Cleanup**: Removed duplicated/no longer needed code in `gadget-tasks` (Mongoose models, internal prompt templates, task executor, AI services, and workspace management).
- **AI Toolbox**: Completed refactor and extraction of the AI toolbox from `@gadget/ai` into `@gadget/ai-toolbox`.
- **Project Manager**: Implemented upgrades across Phases 1-4.
- **Infrastructure**: Added necessary backend routes (`PATCH /api/v1/projects/:projectId/tasks/:taskId/lastRun`) and service methods for atomic task field updates.
- **Project Configuration**: Updated `GadgetTasksConfig` and removed unneeded dependencies (`mongoose`, `dayjs`, `simple-git`, etc.).
- **AI Toolbox**: Completed refactor and extraction from `@gadget/ai` into `@gadget/ai-toolbox`.
- **Project Manager**: Implemented upgrades across Phases 14.
- **Dependencies**: Removed incorrect `simple-git` package; fixed type references.
---
## 2026-05-15 (Thursday)
**Context Window Configuration Added**
**Pull Project, Tool Call Observability, and Context Window Configuration**
The most recent change introduces the `numCtx` (Context Window) setting to the SESSION panel, allowing users to configure the context window size for their AI model sessions. This setting is part of a broader enhancement to the model configuration pipeline that also includes `numPredict` and `maxCompletionTokens` parameters.
Introduced the Pull Project feature for cloning remote repositories, added tool call observability to the chat session view, and added `numCtx` (Context Window) configuration to the SESSION panel. Also refactored ChatSessionView and added the Gab AI affiliate link.
### Changes:
- Added `numCtx` setting to SESSION panel
- Updated model configuration pipeline to include `numPredict`, `numCtx`, and `maxCompletionTokens`
- Modified ChatSessionView to handle new context window settings
- Updated session initialization logic to apply context window configuration
- Added Gab AI affiliate link
- Changed Ollama abort procedure
- **Pull Project**: Initial implementation for cloning remote repositories into the workspace.
- **Observability**: Added tool call observability to the chat session view.
- **File Operations**: Added new file creation capability.
- **SESSION Panel**: Added `numCtx` (Context Window) setting; updated model config pipeline with `numPredict`, `numCtx`, and `maxCompletionTokens`.
- **ChatSessionView**: Refactored for improved structure; added scripts directory.
- **Provider**: Added Gab AI affiliate link; changed Ollama abort procedure.
---
@ -55,84 +57,74 @@ The most recent change introduces the `numCtx` (Context Window) setting to the S
**SubProcess Observability Implementation**
This week focused on implementing comprehensive observability for SubProcess operations within the DroneManager and DroneInspector components, including detailed logging, status tracking, and event emission capabilities.
Implemented comprehensive observability for SubProcess operations within the DroneManager and DroneInspector components, including status tracking, event emission, and UI display of subprocess execution details.
### Changes:
- Implemented Phase 2: SubProcess observability in DroneManager and DroneInspector
- Added subprocess status tracking and event emission
- Updated UI to display subprocess execution details
- Fixed mode change log message formatting
- **SubProcess**: Implemented Phase 1 (SubProcess service and agent tool) and Phase 2 (observability in DroneManager and DroneInspector).
- **UI**: Updated to display subprocess execution details.
- **Fixes**: Fixed mode change log message formatting.
---
## 2026-05-13 (Tuesday)
**Documentation and Editor Improvements**
**CodeMirror Editor Fix and User Mode Documentation**
Documentation updates include adding continuation prompts and remaining steps for User Mode, session summary documentation for MVP completion, and formatting cleanup in AGENTS.md. The editor improvements address a critical issue with CodeMirror editor height constraints in flex layouts.
Fixed a critical CodeMirror editor height constraint in flex layouts, and added documentation for User Mode continuation prompts and MVP completion summary.
### Changes:
- Added continuation prompt and remaining steps for User Mode documentation
- Added session summary for User Mode MVP completion
- Fixed CodeMirror editor height constraint in flex layout
- Minor formatting cleanup in AGENTS.md
- Created new files and prep work for landing page project
- **Editor**: Fixed CodeMirror editor height constraint in flex layout.
- **Documentation**: Added continuation prompt and remaining steps for User Mode; added session summary for MVP completion; formatting cleanup in AGENTS.md.
- **Infrastructure**: Prep work for landing page project.
---
## 2026-05-12 (Monday)
**FILES Panel and Editor Integration**
**FILES Panel, Editor Integration, and Abort Controller**
This week marked a significant milestone with the implementation of the FILES panel foundation featuring lazy-loading file tree capabilities. The implementation replaced react-ace with @uiw/react-codemirror to resolve React 19 compatibility issues and Vite dev server problems.
Major milestone: implemented the FILES panel foundation with lazy-loading file tree, replaced react-ace with @uiw/react-codemirror (React 19 compat), added an abort controller for work order processing, and fixed numerous file tree and layout issues.
### Changes:
- Implemented FILES panel foundation with lazy-loading file tree
- Replaced react-ace with @uiw/react-codemirror
- Fixed flexbox scrolling for FILES panel sidebar
- Added shrink-0 to SESSION and PROJECT panels for proper flex layout
- Fixed file tree scrolling and text selection issues
- Fixed file tree backend recursion breaking lazy loading
- Fixed file tree showing entire workspace instead of project directory
- Fixed file tree duplication and corruption on expand
- Fixed file tree expand/collapse not rendering children
- Added navigation to project in Project Manager using slug
- Fixed ACE editor integration crash — React 19 compat, Vite ?url pattern, Error Boundary
- Fixed file tree duplication and corruption on expand
- **FILES Panel**: Implemented foundation with lazy-loading file tree; fixed scrolling, duplication, corruption, and expand/collapse rendering issues.
- **Editor**: Replaced react-ace with @uiw/react-codemirror for React 19 compatibility; fixed ACE editor crash (Vite `?url` pattern, Error Boundary).
- **Layout**: Fixed flexbox scrolling for sidebar; added `shrink-0` to SESSION and PROJECT panels.
- **Abort Controller**: Implemented abort controller for work order processing; added Aborted status.
- **Navigation**: Added navigation to project in Project Manager using slug.
- **Socket**: Defined missing socket event types; enforced typed events in frontend build.
- **AI**: Fixed OpenAI API tool call processing correctness.
- **Agent**: Moved plan prompt language from common block; added plan for project-specific agent instructions.
---
## 2026-05-11 (Sunday)
**Subagent Processing and Authentication Fixes**
**Subagent Processing, Authentication, and Deployment Documentation**
This weekend's work focused on subagent processing improvements and authentication fixes, including fixes for subagent response handling, session data management, and adding the persona field to sign-in responses.
Focused on subagent processing improvements and authentication fixes, including subagent response handling, session data management, persona field in sign-in responses, and JWT/heartbeat fixes. Added deployment documentation with installation guides, config examples, and systemd service files.
### Changes:
- Fixed subagent response handling and session data
- Added persona field to sign-in response
- Fixed JWT expiration bugs and drone heartbeat timeouts
- Added installation guides, config examples, and systemd service files
- Fixed subagent markdown output whitespace using .subagent-compact.gadget-markdown
- Applied CSS and style fixes for subagent display
- Updated build prompt
- Fixed auth: include persona field in sign-in response
- **Subagent**: Fixed subagent response handling and session data; crushed whitespace in subagent markdown output.
- **Auth**: Added persona field to sign-in response; fixed JWT expiration bugs and drone heartbeat timeouts.
- **ChatSession**: Added reconnect logic; fixed crash.
- **Deployment**: Added installation guides, config examples, and systemd service files.
- **Model Config**: Added `numPredict`, `numCtx`, `maxCompletionTokens` to model configuration pipeline.
- **Style**: CSS and style fixes for subagent display; updated build prompt.
- **Architecture**: Integrated docs/archive for reference; subagents system (written by an agent, for an agent).
---
## 2026-05-10 (Saturday)
**Workspace and Project Philosophy Shift**
**Workspace and Project Philosophy Refinement**
This weekend involved a philosophical shift in how Workspaces and Projects are conceptualized and implemented, with improved separation of concerns and clearer boundaries between the two concepts.
Refined the conceptual model separating Workspaces from Projects, improved the chat interface, and fixed credential provider and API key distribution issues.
### Changes:
- Applied philosophy shifts for Workspaces and Projects
- Updated workspace and project conceptual model
- Improved separation of concerns between workspace and project
- Chat interface fixes and cleanup
- Credential provider fix
- Ensure apiKey is presented to required consumers
- **Architecture**: Applied philosophy shifts for Workspaces and Projects; updated conceptual model.
- **Agent Toolbox**: Refactored and updated agent toolbox.
- **Fixes**: Fixed credential provider; ensured apiKey is presented to required consumers.
- **Chat**: Chat interface fixes and cleanup.
---
@ -140,34 +132,29 @@ This weekend involved a philosophical shift in how Workspaces and Projects are c
**Agentic Workflow Loop Rebuild**
This week involved a complete rebuild of the Agentic Workflow Loop to improve reliability and performance, including better error handling, improved checkpointing, and enhanced event emission capabilities.
Rebuilt the Agentic Workflow Loop from the ground up for improved reliability and performance, with enhanced streaming response handling, chat session auto-naming, and drone-to-IDE log transport.
### Changes:
- Re-built Agentic Workflow Loop with improved reliability
- Enhanced streaming response handling
- Implemented chat session auto-naming with IDE update
- Improved checkpointing and event emission
- GadgetLogTransportSocket and the drone-to-IDE log
- **AWL**: Re-built Agentic Workflow Loop with improved reliability and checkpointing.
- **Streaming**: Enhanced streaming response handling and correctness.
- **Chat Session**: Implemented auto-naming with IDE update.
- **Logging**: Added GadgetLogTransportSocket for drone-to-IDE log streaming.
---
## 2026-05-08 (Thursday)
**Chat Session Heartbeat and User Settings**
**Chat Session Heartbeat, User Settings, and Logging Unification**
This week focused on implementing chat session heartbeat functionality and user settings management, ensuring that active sessions are properly tracked and can be recovered in case of unexpected disconnections.
Implemented chat session heartbeat and session unlock, user settings management, configurable reasoning effort, and unified logging into `@gadget/api` as GadgetLog. Redesigned sign-in form and provider/model selection.
### Changes:
- Implemented chat session heartbeat and session unlock
- Added user settings management
- Made reasoning effort configurable
- Added editable session name with cog icon
- Redesigned sign-in form and presentation
- Integrated persona field in User
- Reworked provider/model selection with save/cancel pattern
- Added navigation to return to Project Manager
- Quick fix for when logging.file.enabled is false
- Refactor: unify logging into @gadget/api as GadgetLog
- **Session**: Implemented chat session heartbeat and session unlock.
- **User Settings**: Added user settings management; made reasoning effort configurable.
- **Auth**: Redesigned sign-in form and presentation; removed sign-up concept; integrated persona field in User.
- **UI**: Reworked provider/model selection with save/cancel pattern; added editable session name with cog icon; added navigation to return to Project Manager.
- **Logging**: Unified logging into `@gadget/api` as GadgetLog; pre-task cleanup to reduce log spam; fixed logging when file logging is disabled.
- **Streaming**: Fixed streaming response handling for Ollama.
---
@ -175,135 +162,119 @@ This week focused on implementing chat session heartbeat functionality and user
**Streaming Responses Implementation**
This week saw the implementation of streaming responses for AI model interactions, including proper handling of streaming data from Ollama and other providers with support for real-time token delivery and response completion tracking.
Implemented streaming responses for AI model interactions, including proper handling of streaming data from Ollama and other providers with real-time token delivery and response completion tracking.
### Changes:
- Implemented streaming responses for Ollama
- Added streaming response handling and correctness improvements
- Created documentation for streaming responses
- Improved real-time token delivery and completion tracking
- **Streaming**: Implemented streaming responses for Ollama with real-time token delivery and completion tracking.
- **Documentation**: Created documentation for streaming responses.
---
## 2026-05-06 (Tuesday)
**Agent Tool and Toolbox Refactoring**
**Agent Tool and Toolbox Architecture**
This week involved significant refactoring of the agent tool and toolbox architecture, including unifying logging into @gadget/api as GadgetLog and restructuring the toolbox to support better tool registration and management.
Significant refactoring of the agent tool and toolbox architecture, establishing the foundational pattern for tool registration and management.
### Changes:
- Refactored agent tool and toolbox architecture
- Unified logging into @gadget/api as GadgetLog
- Improved tool registration and management
- Reduced log spam through pre-task cleanup
- Agent, tools, toolbox, tool loop, AI environment
- **Architecture**: Refactored agent tool and toolbox; established tool registration and management patterns.
- **AI Environment**: Agent, tools, toolbox, tool loop, and AI environment foundation.
---
## 2026-05-05 (Monday)
**Basic Chat System Implementation**
**Basic Chat System Milestone**
This week marked a major milestone with the implementation of a working basic chat system, including provider, model, and mode selection capabilities, along with enhanced AgentService.process method functionality.
Achieved a working basic chat system — the first end-to-end milestone — with provider, model, and mode selection, ChatTurn processing, and agent progress tracking.
### Changes:
- Implemented basic chat system
- Added provider, model, and mode selections
- Enhanced AgentService.process method
- Implemented chat turn processing
- Added agent progress tracking
- **Chat**: Implemented basic working chat system (checkpoint).
- **Selection**: Added provider, model, and mode selections.
- **Processing**: Enhanced AgentService.process method; implemented ChatTurn processing and component.
- **Infrastructure**: Renamed platform.apiKey to platform.gadgetKey; reduced log output.
---
## 2026-05-03 (Saturday)
**Status Message Display Fix**
**Workspace Mode Management and Status Display**
This weekend's work focused on fixing the status message display in the agent interface and implementing workspace mode management improvements with drone status message socket events.
Fixed status message display in the agent interface and implemented workspace mode management with drone status message socket events.
### Changes:
- Fixed status message display in agent interface
- Implemented workspace mode management
- Added drone status message socket events
- Many fixes
- **Status**: Fixed status message display in agent interface.
- **Workspace**: Implemented workspace mode management; added drone status message socket events.
---
## 2026-05-02 (Friday)
**Workspace Mode Switching**
**Workspace Mode Switching with Validation**
This week involved implementing workspace mode switching functionality with proper validation, ensuring that workspace mode changes are validated before being applied, preventing invalid state transitions.
Implemented workspace mode switching with validation, ensuring workspace mode changes are validated before being applied, along with session lock and workspace processing refinements.
### Changes:
- Implemented workspace mode switching with validation
- Added session lock and workspace processing refinements
- Improved workspace management system
- Workspace management progress
- **Workspace**: Implemented workspace mode switching with validation.
- **Session**: Added session lock and workspace processing refinements.
- **Socket**: Socket message and drone workspace cleanup; drone doc updates.
---
## 2026-05-01 (Thursday)
**Welcome to The Grid**
**The Grid Home View and GadgetId Migration**
This week marked the beginning of a new phase with the implementation of the "Welcome to The Grid" home view, including JWT processing fixes, session startup/shutdown/refactoring improvements, and the transition from Types.ObjectId to GadgetId.
Implemented the "Welcome to The Grid" home view, fixed JWT processing, refactored session lifecycle management, and completed the transition from Types.ObjectId to GadgetId across the codebase.
### Changes:
- Implemented "Welcome to The Grid" home view
- Fixed JWT processing
- Refactored session startup, shutdown, and import
- Transitioned from Types.ObjectId to GadgetId
- Added return to Home on sign out
- More populate fixes
- **Home View**: Implemented "Welcome to The Grid" home view; return to Home on sign out.
- **Auth**: Fixed JWT processing.
- **Session**: Refactored session startup, shutdown, and import; fixed import errors.
- **GadgetId**: Completed transition from Types.ObjectId to GadgetId (string alias using nanoid); correctly generate nanoid IDs in default clauses.
---
## 2026-04-30 (Wednesday)
**Socket Protocol Implementation**
**Socket Protocol and Drone Manager**
This week focused on implementing and refining the socket protocol for drone-to-IDE communication, including defining missing socket event types, enforcing typed events in the frontend build, and adding a setting for max Socket.IO HTTP buffer size.
Implemented socket protocol completeness with typed events, created the DroneManager, and finalized Project Manager correctness.
### Changes:
- Implemented socket protocol completeness
- Defined missing socket event types
- Enforced typed events in frontend build
- Added max Socket.IO HTTP buffer size setting
- Created drone manager
- **Socket Protocol**: Implemented socket protocol completeness; defined missing event types; enforced typed events in frontend build.
- **Drone Manager**: Created DroneManager (WIP).
- **Config**: Added setting for max Socket.IO HTTP buffer size.
- **Project Manager**: Wrap-up on Project Manager correctness.
---
## 2026-04-29 (Tuesday)
**Workspace Persistence and Crash Recovery**
**Drone-to-IDE Event Routing and Workspace Persistence**
This week involved implementing workspace persistence and crash recovery capabilities, including adding workspace mode to the gadget-drone process, event emissions to the Agentic Workflow Loop, and drone-to-IDE event routing.
Implemented drone-to-IDE event routing, added event emissions to the Agentic Workflow Loop, and implemented workspace persistence and crash recovery. Added workspace mode to the gadget-drone process.
### Changes:
- Implemented workspace persistence and crash recovery
- Added workspace mode to gadget-drone process
- Added event emissions to Agentic Workflow Loop
- Implemented drone-to-IDE event routing
- Fixed type conflicts and implemented prompt submission
- **Event Routing**: Implemented Drone→IDE event routing (Phase 3); added event emissions to AWL (Phase 4).
- **Workspace**: Added workspace mode to gadget-drone process; implemented workspace persistence and crash recovery (Phase 5).
- **Protocol**: Implemented prompt submission; fixed type conflicts; added socket protocol documentation.
- **Config**: Added max Socket.IO HTTP buffer size setting; standardized interfaces.
---
## 2026-04-28 (Monday)
**Dark Industrial Theme and JWT Authentication**
**Dark Industrial Theme, JWT Auth, and Project Manager**
This week marked a significant visual and architectural milestone with the implementation of the dark industrial theme, Project Manager, and JWT authentication, replacing the previous sign-up concept with a more streamlined sign-in experience.
Significant visual and architectural milestone: implemented the dark industrial theme, Project Manager, and JWT authentication, replacing sign-up with streamlined sign-in.
### Changes:
- Implemented dark industrial theme
- Added Project Manager
- Implemented JWT authentication
- Enforced theme correctly
- Added project service
- Updated DroneRegistration with workspaceDir
- Fix: Darken border colors to match dark industrial theme
- Theme enforced and correctly implemented; e2e tests added for theme
- **Theme**: Implemented dark industrial theme with correct border colors and enforcement.
- **Auth**: Implemented JWT authentication.
- **Project Manager**: Added project service.
- **Models**: Refactored gadget-code model interfaces to `@gadget/api`.
- **Infrastructure**: Added workspaceDir to DroneRegistration; E2E tests for theme.
---
@ -311,8 +282,8 @@ This week marked a significant visual and architectural milestone with the imple
**Initial Commit**
The project was initialized with the initial commit, establishing the foundation for all subsequent development.
The project was initialized, establishing the foundation for all subsequent development.
### Changes:
- Initial project commit
- Established basic project structure
- Initial project commit.
- Established basic project structure.

View File

@ -253,5 +253,5 @@ Apache 2.0 — See [LICENSE](./LICENSE) for details.
---
**Status:** Production-ready foundation with complete Chat Session UI
**Status:** v1.0.1 — First release. Self-hosted agentic engineering platform with local/self-hosted AI model support, complete Chat Session UI, subagent processing, and workspace management.
**Last Updated:** May 17, 2026

120
RELEASE.md Normal file
View File

@ -0,0 +1,120 @@
GADGET CODE v1.0.1
NAME: Liberation
HASH: ff46c35d38e29be64d9eca0ccc18e8a7f5c3d8ab
TAG: v1.0.1
SUMMARY:
Today marks the Liberation of Gadget Code — the first public release of a self-hosted agentic engineering platform that puts you in control of your code, your models, and your infrastructure.
Over 200 commits spanning 21 days of intensive development, Gadget Code has grown from an initial commit into a complete platform for autonomous software engineering. And every line of it is Apache-2.0 licensed, fully open source, and designed to run on *your* terms.
## What Is Gadget Code?
Gadget Code is an **Agentic Engineering Platform (AEP)** — a browser-based IDE that drives autonomous AI agents to perform real software engineering work on your behalf. Unlike cloud-locked alternatives, Gadget Code runs entirely in your environment: your servers, your data, your rules.
The architecture is straightforward and powerful:
```
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Browser IDE │────▶│ gadget-code │────▶│ gadget-drone │
│ (React 19) │◀────│ (Express 5) │◀────│ (Worker) │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
│ Socket.IO │ MongoDB │ Files
│ JWT Auth │ Redis │ Git
```
A user creates a project in the browser IDE, selects a drone instance, enters a prompt, and the drone executes the Agentic Workflow Loop — thinking, responding, calling tools, spawning subagents — all streamed back in real time.
## Your Models, Your Way
This is what Liberation means. Gadget Code ships with first-class support for **Ollama** and any **OpenAI-compatible API**. Run local models on your own GPU. Self-host an inference endpoint behind your firewall. Use a commercial provider when it suits you. Mix and match per session. The `@gadget/ai` package provides a unified abstraction — no consumer code ever imports an SDK directly. Swap providers without changing a line of application logic.
The model configuration pipeline supports `numCtx` (context window), `numPredict`, and `maxCompletionTokens` settings, giving you fine-grained control over how your models behave.
## Complete Agentic Engineering Platform
Gadget Code isn't a chatbot wrapper. It's a full-stack engineering environment:
- **Project Manager** — Create projects, select available drone instances, manage chat session history.
- **Chat Session View** — Real-time streaming responses with collapsible thinking content, tool call summaries, session statistics, and per-session model/mode selection.
- **Agentic Workflow Loop** — The drone executes a multi-turn reasoning loop: think, respond, call tools, observe results, and iterate. Work orders are abortable, and the loop supports checkpointing for crash recovery.
- **Subagent Processing** — Agents can spawn specialized subagents for decomposition tasks. Subagent context is managed independently and streamed back to the IDE in real time.
- **FILE Panel** — Lazy-loading file tree with full workspace navigation and CodeMirror editor integration (React 19 compatible).
- **Workspace Management** — Each drone manages a workspace directory with crash recovery via the `.gadget/` directory and intelligent startup that detects the workspace by walking up the file hierarchy.
- **Scheduled Tasks (gadget-tasks)** — A headless IDE client that automates the browser flow on a cron schedule. It drives the existing gadget-code platform via the same REST API and Socket.IO protocol the browser uses — no duplicated logic.
- **Pull Project** — Clone remote repositories directly into your workspace.
- **Abort Controller** — Cancel in-progress work orders with proper state cleanup.
## Configuration and Dependencies
Gadget Code requires:
- **Node.js 22+** and **pnpm 10+**
- **MongoDB** on `localhost:27017`
- **Redis** on `localhost:6379`
- **SSL certificates** in the `ssl/` directory for dev servers
- An **Ollama** instance or **OpenAI-compatible API** endpoint for AI features
The monorepo is organized as follows:
| Package | Role |
| -------------------- | --------------------------------------------------------------- |
| `gadget-code` | Web service — agentic IDE, browser UI, API server |
| `gadget-drone` | Worker process — runs the agentic workflow loop |
| `gadget-tasks` | Scheduled task worker — headless IDE client for cron-driven tasks |
| `@gadget/ai` | Shared AI API abstraction — Ollama and OpenAI |
| `@gadget/ai-toolbox` | Shared AI tool implementations — search, file, plan, subagent |
| `@gadget/api` | Shared TypeScript interfaces — common types across all packages |
| `@gadget/config` | Shared YAML config loader — per-package configuration |
AI providers are managed via CLI:
```bash
# Add Ollama (no API key needed)
pnpm cli provider add "Local Ollama" ollama http://localhost:11434
# Add OpenAI-compatible provider
pnpm cli provider add "OpenAI" openai https://api.openai.com $OPENAI_API_KEY
# Discover available models
pnpm cli provider probe <provider-id>
```
## The Journey to v1.0.1
This release represents 21 days of development from April 27 through May 17, 2026:
- **Days 12** (Apr 2728): Project initialization, dark industrial theme, JWT authentication, Project Manager, drone-to-IDE event routing, workspace persistence and crash recovery.
- **Days 34** (Apr 2930): Socket protocol completeness, DroneManager, GadgetId migration from ObjectId to nanoid-based string IDs, "Welcome to The Grid" home view.
- **Days 56** (May 13): Workspace mode switching with validation, session locks, basic chat system milestone — the first end-to-end working demo.
- **Days 78** (May 56): Agent tool and toolbox architecture, tool registration patterns, AI environment foundation.
- **Day 9** (May 7): Streaming responses implementation — real-time token delivery from Ollama.
- **Day 10** (May 8): Chat session heartbeat, user settings, logging unification into `@gadget/api` as GadgetLog, redesigned sign-in form.
- **Day 9 continued** (May 9): Agentic Workflow Loop rebuild, chat session auto-naming, drone-to-IDE log transport.
- **Day 11** (May 10): Workspace/project philosophy refinement, agent toolbox refactor, credential provider fixes.
- **Day 12** (May 11): Subagent processing, authentication fixes, deployment documentation with systemd service files.
- **Day 13** (May 12): FILES panel with lazy-loading file tree, CodeMirror editor integration (replacing react-ace for React 19 compat), abort controller.
- **Day 14** (May 13): Editor height fixes, User Mode documentation.
- **Day 15** (May 14): SubProcess observability — tracking spawned processes in the DroneManager and DroneInspector.
- **Day 16** (May 15): Pull Project feature, tool call observability, context window configuration, Gab AI affiliate link.
- **Days 1718** (May 1617): AI toolbox extraction into `@gadget/ai-toolbox`, Project Manager upgrades, gadget-tasks headless client architecture, release hardening.
## Project Direction
Gadget Code is built on a simple conviction: **your code, your models, your infrastructure**. The cloud AI ecosystem has moved toward vendor lock-in at every layer — proprietary models, closed platforms, data harvesting. Liberation is the alternative. Every component of Gadget Code is self-hosted. Every AI call goes through your providers. Every file stays on your disk. Every model runs on your hardware if you want it to.
This is also the first release where the release document itself is authored by Gadget — the AI agent — as part of the automated release workflow. The agent that writes code for you also writes the release notes. We think that's fitting.
## Get Started
Get the latest release at **https://g4dge7.com/** — the official home of Gadget Code.
Apache-2.0 licensed. Fully open source. No vendor lock-in. No data harvesting. No cloud dependency. Just you, your models, and your code.
That's Liberation.
---
*This RELEASE.md was authored by Gadget — the AI agent itself — as part of the automated release workflow. Gadget Code is licensed under the Apache-2.0 license. Both of these facts — an AI agent that can produce its own release notes, and a permissive open-source license that lets you build anything — are great reasons to switch to Gadget Code today. Get the latest release at https://g4dge7.com/.*

View File

@ -28,7 +28,7 @@ export default function Clock() {
}, []);
return (
<div className="p-3">
<div className="p-3 shrink-0">
<div className="text-xs font-semibold text-text-muted uppercase tracking-wider mb-2">
Clock
</div>

View File

@ -269,53 +269,12 @@ function DashboardSidebar({
};
return (
<aside className="w-64 border-l border-border-subtle bg-bg-secondary overflow-y-auto">
<aside className="w-64 border-l border-border-subtle bg-bg-secondary flex flex-col overflow-hidden min-h-0">
<Clock />
<div className="p-3 border-t border-border-subtle">
<div className="text-xs font-semibold text-text-muted uppercase tracking-wider mb-2">
Recent Chats
</div>
{loading ? (
<p className="text-sm text-text-muted px-2">Loading...</p>
) : recentChats.length === 0 ? (
<p className="text-sm text-text-muted px-2">No recent chats.</p>
) : (
<div className="space-y-1">
{recentChats.map((session) => (
<button
key={session._id}
onClick={() => handleOpenChat(session)}
className="w-full text-left px-2 py-1.5 text-sm text-text-secondary hover:bg-bg-tertiary hover:text-text-primary rounded transition-colors"
>
<div className="flex items-center justify-between gap-1">
<span className="truncate font-medium text-xs">{session.name || 'Untitled'}</span>
<span className={`text-[10px] px-1.5 py-0.5 rounded-full font-medium shrink-0 ${modeBadgeColors[session.mode] || 'bg-gray-500/20 text-gray-400'}`}>
{session.mode}
</span>
</div>
<div className="flex items-center justify-between gap-1 mt-0.5">
<span className="text-[11px] text-text-muted truncate">{getProjectName(session)}</span>
<span className="text-[10px] text-text-muted shrink-0">
{formatRelativeTime(session.lastMessageAt || session.createdAt)}
</span>
</div>
</button>
))}
</div>
)}
{noDroneMessage && (
<p className="text-xs text-yellow-400 mt-2 px-2">{noDroneMessage}</p>
)}
{selectedDrone && (
<p className="text-[10px] text-text-muted mt-2 px-2 italic">
Select a chat to resume with {selectedDrone.hostname}
</p>
)}
</div>
<div className="p-3 border-t border-border-subtle">
<div className="flex items-center justify-between text-xs font-semibold text-text-muted uppercase tracking-wider mb-2">
{/* Projects */}
<div className="flex-1 min-h-0 flex flex-col border-t border-border-subtle">
<div className="shrink-0 px-3 pt-3 pb-2 flex items-center justify-between text-xs font-semibold text-text-muted uppercase tracking-wider">
<span>Projects</span>
<Link
to="/projects"
@ -324,6 +283,7 @@ function DashboardSidebar({
[+]
</Link>
</div>
<div className="flex-1 min-h-0 overflow-y-auto px-3 pb-3">
{loading ? (
<p className="text-sm text-text-muted px-2">Loading...</p>
) : projects.length === 0 ? (
@ -342,9 +302,11 @@ function DashboardSidebar({
</div>
)}
</div>
</div>
<div className="p-3 border-t border-border-subtle">
<div className="flex items-center justify-between text-xs font-semibold text-text-muted uppercase tracking-wider mb-2">
{/* Drones */}
<div className="flex-1 min-h-0 flex flex-col border-t border-border-subtle">
<div className="shrink-0 px-3 pt-3 pb-2 flex items-center justify-between text-xs font-semibold text-text-muted uppercase tracking-wider">
<span>Drones</span>
<Link
to="/drones"
@ -372,6 +334,7 @@ function DashboardSidebar({
</svg>
</Link>
</div>
<div className="flex-1 min-h-0 overflow-y-auto px-3 pb-3">
{loading ? (
<p className="text-sm text-text-muted px-2">Loading...</p>
) : drones.length === 0 ? (
@ -418,6 +381,54 @@ function DashboardSidebar({
</div>
)}
</div>
</div>
{/* Recent Chats */}
<div className="flex-1 min-h-0 flex flex-col border-t border-border-subtle">
<div className="shrink-0 px-3 pt-3 pb-2 text-xs font-semibold text-text-muted uppercase tracking-wider">
Recent Chats
</div>
<div className="flex-1 min-h-0 overflow-y-auto px-3 pb-3">
{loading ? (
<p className="text-sm text-text-muted px-2">Loading...</p>
) : recentChats.length === 0 ? (
<p className="text-sm text-text-muted px-2">No recent chats.</p>
) : (
<div className="space-y-1">
{recentChats.map((session) => (
<button
key={session._id}
onClick={() => handleOpenChat(session)}
className="w-full text-left px-2 py-1.5 text-sm text-text-secondary hover:bg-bg-tertiary hover:text-text-primary rounded transition-colors"
>
<div className="flex items-center justify-between gap-1">
<span className="truncate font-medium text-xs">{session.name || 'Untitled'}</span>
<span className={`text-[10px] px-1.5 py-0.5 rounded-full font-medium shrink-0 ${modeBadgeColors[session.mode] || 'bg-gray-500/20 text-gray-400'}`}>
{session.mode}
</span>
</div>
<div className="flex items-center justify-between gap-1 mt-0.5">
<span className="text-[11px] text-text-muted truncate">{getProjectName(session)}</span>
<span className="text-[10px] text-text-muted shrink-0">
{formatRelativeTime(session.lastMessageAt || session.createdAt)}
</span>
</div>
</button>
))}
</div>
)}
</div>
<div className="shrink-0 px-3 pb-3">
{noDroneMessage && (
<p className="text-xs text-yellow-400 mt-2 px-2">{noDroneMessage}</p>
)}
{selectedDrone && (
<p className="text-[10px] text-text-muted mt-2 px-2 italic">
Select a chat to resume with {selectedDrone.hostname}
</p>
)}
</div>
</div>
</aside>
);
@ -447,7 +458,7 @@ export default function Home({ user }: HomeProps) {
}
const mainContent = selectedDrone ? (
<div className="relative z-10 flex-1 flex">
<div className="relative z-10 flex-1 flex min-h-0">
<DroneInspector
drone={selectedDrone}
onClose={() => setSelectedDrone(null)}
@ -463,8 +474,8 @@ export default function Home({ user }: HomeProps) {
/>
</div>
) : (
<div className="relative z-10 flex-1 flex flex-col">
<div className="flex-1 flex">
<div className="relative z-10 flex-1 flex flex-col min-h-0">
<div className="flex-1 flex min-h-0">
<div className="flex-1 flex items-center justify-center p-8">
<div className="text-center">
<h1 className="text-2xl font-semibold mb-4">

View File

@ -19,6 +19,14 @@ vi.mock("../src/services/socket");
vi.mock("../src/services/chat-session");
vi.mock("../src/models/chat-turn");
vi.mock("../src/models/chat-session");
vi.mock("../src/lib/tab-lock", () => ({
default: {
acquire: vi.fn().mockResolvedValue({ success: true }),
release: vi.fn().mockResolvedValue(undefined),
refresh: vi.fn().mockResolvedValue(true),
getInfo: vi.fn().mockResolvedValue(null),
},
}));
describe("CodeSession", () => {
let mockSocket: any;
@ -270,6 +278,14 @@ describe("CodeSession", () => {
ChatSessionService.generateSessionNameFromPrompt,
).mockResolvedValue(namedSession as any);
// Mock drone to accept the work order so the success callback runs
mockDroneSession.socket.emit = vi.fn((event: string, ...args: any[]) => {
const callback = args[args.length - 1];
if (typeof callback === "function") {
callback(true, "work order accepted");
}
});
await codeSession.onSubmitPrompt("build a rest api", cb);
expect(
@ -334,7 +350,7 @@ describe("CodeSession", () => {
});
describe("onRequestSessionLock", () => {
it("should set selected drone, chat session, and project on success", () => {
it("should set selected drone, chat session, and project on success", async () => {
const mockDroneSession = {
socket: {
emit: vi.fn((event: string, ...args: any[]) => {
@ -357,8 +373,12 @@ describe("CodeSession", () => {
callback,
);
// The inner callback is async (awaits TabLock.acquire), so we need to
// wait for the microtask queue to flush before asserting
await vi.waitFor(() => {
expect(callback).toHaveBeenCalledWith(true, mockChatSession._id);
});
});
it("should not set session data on failure", () => {
const mockDroneSession = {

View File

@ -1,6 +1,6 @@
{
"name": "gadget-workspace",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"description": "Gadget Code monorepo workspace root",
"packageManager": "pnpm@10.33.2",

89
release Executable file
View File

@ -0,0 +1,89 @@
#!/bin/bash
set -euo pipefail
MAIN_BRANCH="master"
DEVELOP_BRANCH="develop"
VALID_LEVELS="major minor patch"
# ── Validation ────────────────────────────────────────────────────────────────
if [ -z "${1:-}" ]; then
echo "ERROR: Must specify the release level: major, minor, patch" >&2
exit 1
fi
RELEASE_LEVEL="$1"
if ! echo "$VALID_LEVELS" | grep -qw "$RELEASE_LEVEL"; then
echo "ERROR: Invalid release level '$RELEASE_LEVEL'. Must be one of: $VALID_LEVELS" >&2
exit 1
fi
# ── Pre-flight checks ────────────────────────────────────────────────────────
BRANCH=$(git rev-parse --abbrev-ref HEAD)
# Ensure we're in a git repo
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "ERROR: Not inside a git repository" >&2
exit 1
fi
# Check for a clean working tree
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "ERROR: Working tree has uncommitted changes. Commit or stash before releasing." >&2
git status --short >&2
exit 1
fi
# Verify both remotes exist
for remote in origin dtp; do
if ! git remote get-url "$remote" >/dev/null 2>&1; then
echo "ERROR: Git remote '$remote' not found" >&2
exit 1
fi
done
# Verify branches exist locally
for branch in "$MAIN_BRANCH" "$DEVELOP_BRANCH"; do
if ! git rev-parse --verify "$branch" >/dev/null 2>&1; then
echo "ERROR: Branch '$branch' does not exist locally" >&2
exit 1
fi
done
# ── Save starting branch for rollback ────────────────────────────────────────
STARTING_BRANCH="$BRANCH"
# ── Step 1: Update develop and bump version ──────────────────────────────────
echo ">>> Switching to $DEVELOP_BRANCH..."
git checkout "$DEVELOP_BRANCH"
echo ">>> Bumping version ($RELEASE_LEVEL)..."
NEW_VERSION=$(npm version "$RELEASE_LEVEL" -m "release: %s")
echo " Version bumped to $NEW_VERSION"
# ── Step 2: Push develop + tags to both remotes ──────────────────────────────
echo ">>> Pushing $DEVELOP_BRANCH to origin..."
git push origin "$DEVELOP_BRANCH" --follow-tags
echo ">>> Pushing $DEVELOP_BRANCH to dtp..."
git push dtp "$DEVELOP_BRANCH" --follow-tags
# ── Step 3: Merge develop into master ────────────────────────────────────────
echo ">>> Switching to $MAIN_BRANCH..."
git checkout "$MAIN_BRANCH"
echo ">>> Merging $DEVELOP_BRANCH into $MAIN_BRANCH..."
git merge "$DEVELOP_BRANCH"
# ── Step 4: Push master + tags to both remotes ───────────────────────────────
echo ">>> Pushing $MAIN_BRANCH to origin..."
git push origin "$MAIN_BRANCH" --follow-tags
echo ">>> Pushing $MAIN_BRANCH to dtp..."
git push dtp "$MAIN_BRANCH" --follow-tags
# ── Step 5: Return to develop ────────────────────────────────────────────────
echo ">>> Switching back to $DEVELOP_BRANCH..."
git checkout "$DEVELOP_BRANCH"
echo ">>> Release $NEW_VERSION complete!"