The tools have evolved. Have you? https://g4dge7.com/
Go to file
Rob Colbert 009863cf2b fix: resolve drone heartbeat timeouts and JWT expiration bugs
This commit addresses two interrelated issues causing drones to
de-register and users to be forcibly signed out:

## Heartbeat Timeout Fixes

1. Move heartbeat interval to a Web Worker (not subject to browser
   tab throttling). Chrome throttles setInterval in background tabs
   to ~1/min, which causes the 19s heartbeat to miss the drone's
   timeout timer. The Web Worker fires reliably regardless of tab
   visibility.

2. Add visibilitychange handler: when the tab becomes visible again,
   send an immediate heartbeat to reset the drone's timer after any
   throttling that may have occurred.

3. Fix onReleaseSessionLock to clear the heartbeat timer. Previously,
   releasing the lock left the 60s timer running, causing a spurious
   timeout and status emit after the lock was already released.

4. Increase drone heartbeat timeout from 60s to 120s. With the Web
   Worker fix, heartbeats should be reliable, but doubling the timeout
   provides a generous safety margin.

5. Add socket disconnect/reconnect handlers on the drone side. On
   disconnect, clear the heartbeat timer. On reconnect, re-emit drone
   status so the platform knows the drone is alive.

6. Configure Socket.IO pingInterval/pingTimeout explicitly (25s/60s)
   instead of relying on defaults.

## JWT Expiration Fixes

1. Increase WebToken DB record expiration from 1 hour to 7 days. The
   1-hour expiration was the real session lifetime gate (the JWT crypto
   exp was already 24h), and it was far too aggressive for a dev tool.

2. Fix web /auth/renew-token endpoint to use req.user from the session
   cookie instead of verifyJsonWebToken(req.body.token). This eliminates
   the catch-22 where an expired token cannot be used to request its
   own renewal.

3. Fix token refresh response parsing. The API v1 renew-token endpoint
   returns { success: true, token } at the top level, but the frontend
   was looking for json.data?.token, causing every refresh to fail.

4. Add proactive token refresh: check the JWT exp claim before each
   request and refresh if expiring within 5 minutes. This avoids
   unnecessary 401 errors and the resulting socket disconnections.

5. Update socket JWT on token renewal via a callback registered in
   App.tsx. This ensures that future socket reconnections use the new
   token instead of the expired one.

## Files Modified

- gadget-code/frontend/src/workers/heartbeat.worker.ts (NEW)
- gadget-code/frontend/src/lib/socket.ts
- gadget-code/frontend/src/lib/api.ts
- gadget-code/frontend/src/App.tsx
- gadget-code/src/services/session.ts
- gadget-code/src/controllers/auth.ts
- gadget-code/src/services/socket.ts
- gadget-drone/src/gadget-drone.ts
2026-05-11 17:46:09 -04:00
.opencode/plans checkpoint 2026-04-29 18:59:42 -04:00
.vscode cleanup 2026-05-07 00:59:15 -04:00
assets added for placement in UI 2026-05-05 05:28:29 -04:00
docs docs: add installation guides, config examples, and systemd service files 2026-05-11 13:50:19 -04:00
gadget-code fix: resolve drone heartbeat timeouts and JWT expiration bugs 2026-05-11 17:46:09 -04:00
gadget-drone fix: resolve drone heartbeat timeouts and JWT expiration bugs 2026-05-11 17:46:09 -04:00
packages feat: add numPredict, numCtx, maxCompletionTokens to model config pipeline 2026-05-11 13:50:19 -04:00
.gitignore integrate docs/archive/* for reference until no longer needed 2026-05-11 11:30:02 -04:00
AGENTS.md quick updates 2026-05-08 03:05:01 -04:00
gadget.code-workspace socket message and drone workspace cleanup 2026-05-02 02:46:45 -04:00
package.json created by merging gadget-code and gadget-drone 2026-04-28 09:20:37 -04:00
pnpm-lock.yaml checkpoint that I plan to delete 2026-05-09 14:52:59 -04:00
pnpm-workspace.yaml created by merging gadget-code and gadget-drone 2026-04-28 09:20:37 -04:00
README.md agent, tools, toolbox, tool loop, AI environment 2026-05-07 00:10:57 -04:00
terms-of-service.md a pile of small fixes 2026-05-11 07:08:18 -04:00

Gadget Code

A self-hosted Agentic Engineering Platform (AEP) — an IDE that drives autonomous AI agents to perform software engineering work on your behalf, running in your own environment.

Quick Start

# Install dependencies
pnpm install

# Start backend (Terminal 1)
cd gadget-code
pnpm dev:backend

# Start frontend (Terminal 2)
cd gadget-code/frontend
pnpm dev

# Open browser to https://localhost:5174

Projects

Package Role
gadget-code Web service — agentic IDE, browser UI, API server
gadget-drone Worker process — runs the agentic workflow loop in workspace directories
@gadget/ai Shared AI API abstraction — Ollama and OpenAI
@gadget/api Shared TypeScript interfaces — common types across all packages

Architecture

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│  Browser IDE │────▶│  gadget-code │────▶│ gadget-drone │
│  (React 19)  │◀────│ (Express 5)  │◀────│  (Worker)    │
└──────────────┘     └──────────────┘     └──────────────┘
       │                    │                      │
       │ Socket.IO          │ MongoDB              │ Files
       │ JWT Auth           │ Redis                │ Git

How It Works

  1. User creates a project in the browser IDE
  2. User selects a drone instance to work on the project
  3. User enters a prompt in the Chat Session view
  4. Prompt flows IDE → Web → Drone via Socket.IO
  5. Drone executes the Agentic Workflow Loop (AWL)
  6. Streaming response flows back: thinking → response → tool calls
  7. Results persist in MongoDB as ChatTurn records

AI Provider Setup

Before using AI features, add a provider via CLI:

# Add Ollama provider (no API key needed)
cd gadget-code
pnpm cli provider add "Local Ollama" ollama http://localhost:11434

# Add OpenAI provider
pnpm cli provider add "OpenAI" openai https://api.openai.com $OPENAI_API_KEY

# List providers
pnpm cli provider ls

# Probe provider for models (discovers available models)
pnpm cli provider probe <provider-id>

User Management

# Add a user
pnpm cli user add user@example.com password123 "Display Name"

# Grant admin rights
pnpm cli admin grant user@example.com

# Reset password
pnpm cli user password user@example.com newpassword

Development

Prerequisites

  • Node.js 22+
  • pnpm 10+
  • MongoDB on localhost:27017
  • Redis on localhost:6379
  • SSL certificates in ssl/ directory (for dev servers)

Build

# Build all packages
pnpm -r build

# Build specific package
pnpm --filter @gadget/ai build
pnpm --filter gadget-drone build
pnpm --filter gadget-code build

Run Development Servers

# Backend (gadget-code directory)
cd gadget-code
pnpm dev:backend
# Runs on https://localhost:3443

# Frontend (gadget-code/frontend directory)
cd gadget-code/frontend
pnpm dev
# Runs on https://localhost:5174

# Drone worker (in a workspace directory)
cd ~/my-gadget-workspace
pnpm --filter gadget-drone dev

Testing

# Unit tests (gadget-code directory)
cd gadget-code
pnpm test

# E2E tests with Playwright (requires running dev servers)
npx playwright test tests/e2e/project-manager.test.ts
npx playwright test tests/e2e/chat-session.test.ts

# Seed test data for E2E tests
npx tsx scripts/seed-test-drones.ts

Key Features

Project Manager

  • Create and manage projects
  • Select available drones (filters out offline)
  • View chat session history
  • Create new chat sessions with provider/model selection

Chat Session View

  • Real-time streaming responses
  • Collapsible thinking content
  • Tool call summaries
  • Model/mode selection per session
  • Session statistics (tool calls, file ops, subagents)

Workspace Management

  • Each drone manages a workspace directory
  • Projects cloned into workspace by slug
  • Crash recovery via .gadget/ directory
  • Workspace persistence across restarts

AI API Abstraction

All AI calls route through @gadget/ai. No consumer code imports Ollama or OpenAI SDKs directly.

// Correct: Use the factory
import { createAiApi } from '@gadget/ai';
const ai = createAiApi(providerConfig);

// Incorrect: Don't import SDKs directly
import { Ollama } from 'ollama'; // ❌

See packages/ai/README.md for the full API reference.

Documentation

Monorepo Structure

gadget/
├── packages/ai/           # @gadget/ai — AI API abstraction
├── packages/api/          # @gadget/api — Shared interfaces
├── gadget-code/           # Web service + browser IDE
│   ├── src/               # Backend (Express, Socket.IO, Mongoose)
│   ├── frontend/          # Frontend (React, Vite, Tailwind)
│   └── tests/             # Unit + E2E tests
├── gadget-drone/          # Worker process
│   ├── src/               # Drone implementation
│   └── docs/              # Drone documentation
└── docs/                  # Architecture & protocol docs

License

Apache 2.0 — See LICENSE for details.


Status: Production-ready foundation with complete Chat Session UI
Last Updated: April 29, 2026