Merge branch 'develop' of git.digitaltelepresence.com:rob/gadget into develop
This commit is contained in:
commit
0437ca66d8
273
CHANGE.md
273
CHANGE.md
@ -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 1–4. 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 1–4.
|
||||
- **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.
|
||||
|
||||
@ -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
120
RELEASE.md
Normal 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 1–2** (Apr 27–28): Project initialization, dark industrial theme, JWT authentication, Project Manager, drone-to-IDE event routing, workspace persistence and crash recovery.
|
||||
- **Days 3–4** (Apr 29–30): Socket protocol completeness, DroneManager, GadgetId migration from ObjectId to nanoid-based string IDs, "Welcome to The Grid" home view.
|
||||
- **Days 5–6** (May 1–3): Workspace mode switching with validation, session locks, basic chat system milestone — the first end-to-end working demo.
|
||||
- **Days 7–8** (May 5–6): 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 17–18** (May 16–17): 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/.*
|
||||
@ -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>
|
||||
|
||||
@ -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,27 +283,30 @@ function DashboardSidebar({
|
||||
[+]
|
||||
</Link>
|
||||
</div>
|
||||
{loading ? (
|
||||
<p className="text-sm text-text-muted px-2">Loading...</p>
|
||||
) : projects.length === 0 ? (
|
||||
<p className="text-sm text-text-muted px-2">No projects yet.</p>
|
||||
) : (
|
||||
<div className="space-y-1">
|
||||
{projects.map((project) => (
|
||||
<button
|
||||
key={project._id}
|
||||
onClick={() => navigate(`/projects/${project.slug}`)}
|
||||
className="w-full text-left px-2 py-1.5 text-sm text-text-secondary hover:bg-bg-tertiary hover:text-text-primary rounded truncate transition-colors"
|
||||
>
|
||||
{project.name}
|
||||
</button>
|
||||
))}
|
||||
</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 ? (
|
||||
<p className="text-sm text-text-muted px-2">No projects yet.</p>
|
||||
) : (
|
||||
<div className="space-y-1">
|
||||
{projects.map((project) => (
|
||||
<button
|
||||
key={project._id}
|
||||
onClick={() => navigate(`/projects/${project.slug}`)}
|
||||
className="w-full text-left px-2 py-1.5 text-sm text-text-secondary hover:bg-bg-tertiary hover:text-text-primary rounded truncate transition-colors"
|
||||
>
|
||||
{project.name}
|
||||
</button>
|
||||
))}
|
||||
</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,51 +334,100 @@ function DashboardSidebar({
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
{loading ? (
|
||||
<p className="text-sm text-text-muted px-2">Loading...</p>
|
||||
) : drones.length === 0 ? (
|
||||
<p className="text-sm text-text-muted px-2">No drones available.</p>
|
||||
) : (
|
||||
<div className="space-y-1">
|
||||
{drones.map((drone) => (
|
||||
<button
|
||||
key={drone._id}
|
||||
onClick={() => onSelectDrone(drone)}
|
||||
className={`w-full text-left px-2 py-1 rounded transition-colors ${
|
||||
selectedDrone?._id === drone._id
|
||||
? "bg-brand text-white"
|
||||
: "text-text-secondary hover:bg-bg-tertiary hover:text-text-primary"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span
|
||||
className={`w-2 h-2 rounded-full shrink-0 ${
|
||||
drone.status === "available"
|
||||
? "bg-green-500"
|
||||
: "bg-yellow-500"
|
||||
}`}
|
||||
/>
|
||||
<div className="overflow-hidden">
|
||||
<div className="text-sm truncate">{drone.hostname}</div>
|
||||
{drone.workspaceDir && (
|
||||
<div
|
||||
className={`text-xs truncate ${
|
||||
selectedDrone?._id === drone._id
|
||||
? "text-white/70"
|
||||
: "text-text-muted"
|
||||
}`}
|
||||
>
|
||||
{drone.workspaceDir.length > 24
|
||||
? "..." + drone.workspaceDir.slice(-21)
|
||||
: drone.workspaceDir}
|
||||
</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 ? (
|
||||
<p className="text-sm text-text-muted px-2">No drones available.</p>
|
||||
) : (
|
||||
<div className="space-y-1">
|
||||
{drones.map((drone) => (
|
||||
<button
|
||||
key={drone._id}
|
||||
onClick={() => onSelectDrone(drone)}
|
||||
className={`w-full text-left px-2 py-1 rounded transition-colors ${
|
||||
selectedDrone?._id === drone._id
|
||||
? "bg-brand text-white"
|
||||
: "text-text-secondary hover:bg-bg-tertiary hover:text-text-primary"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span
|
||||
className={`w-2 h-2 rounded-full shrink-0 ${
|
||||
drone.status === "available"
|
||||
? "bg-green-500"
|
||||
: "bg-yellow-500"
|
||||
}`}
|
||||
/>
|
||||
<div className="overflow-hidden">
|
||||
<div className="text-sm truncate">{drone.hostname}</div>
|
||||
{drone.workspaceDir && (
|
||||
<div
|
||||
className={`text-xs truncate ${
|
||||
selectedDrone?._id === drone._id
|
||||
? "text-white/70"
|
||||
: "text-text-muted"
|
||||
}`}
|
||||
>
|
||||
{drone.workspaceDir.length > 24
|
||||
? "..." + drone.workspaceDir.slice(-21)
|
||||
: drone.workspaceDir}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
</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">
|
||||
|
||||
@ -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,7 +373,11 @@ describe("CodeSession", () => {
|
||||
callback,
|
||||
);
|
||||
|
||||
expect(callback).toHaveBeenCalledWith(true, mockChatSession._id);
|
||||
// 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", () => {
|
||||
|
||||
@ -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
89
release
Executable 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!"
|
||||
Loading…
Reference in New Issue
Block a user