## Problem
`dispatchTask()` shells out to `openclaw gateway call sessions.patch` which
times out when the gateway is busy, causing:
1. Notifications never fire (they're at the end of dispatchTask)
2. Worker state may not be recorded
3. Workers run silently
## Solution (3 changes)
### 1. Make `ensureSession` fire-and-forget
Session key is deterministic, so we don't need to wait for confirmation.
Health check catches orphaned state later.
### 2. Use runtime API for notifications instead of CLI
Pass `runtime` through opts and use direct API calls:
- `runtime.channel.telegram.sendMessageTelegram()`
- `runtime.channel.whatsapp.sendMessageWhatsApp()`
- etc.
### 3. Move notification before session dispatch
Fire workerStart/workerComplete notifications early (after label transition)
before the session calls that can timeout.
## Files Changed
- lib/dispatch.ts — fire-and-forget ensureSession, early notification, accept runtime
- lib/notify.ts — use runtime API for direct channel sends
- lib/services/pipeline.ts — early notification, accept runtime
- lib/services/tick.ts — pass runtime through to dispatchTask
- lib/tool-helpers.ts — accept runtime in tickAndNotify
- lib/tools/work-start.ts — pass api.runtime to dispatchTask
- lib/tools/work-finish.ts — pass api.runtime to executeCompletion/tickAndNotify
## Changes
- Remove `activeSessions` parameter from health check (was never populated)
- Add gateway session lookup via `openclaw gateway call status`
- Add issue label lookup via `provider.getIssue(issueId)`
- Implement detection matrix with 6 issue types:
- session_dead: active worker but session missing in gateway
- label_mismatch: active worker but issue not in Doing/Testing
- stale_worker: active for >2h
- stuck_label: inactive but issue has Doing/Testing label
- orphan_issue_id: inactive but issueId set
- issue_gone: active but issue deleted/closed
## Files
- lib/services/health.ts — complete rewrite with three-source triangulation
- lib/tools/health.ts — remove activeSessions param, fetch sessions from gateway
- lib/services/heartbeat.ts — remove empty activeSessions calls, pass sessions map
Major changes:
- Add autoconfigure_models tool for intelligent model assignment
- Implement LLM-based model selection using openclaw agent
- Improve onboarding flow with better model access checks
- Update README with clearer installation and onboarding instructions
Technical improvements:
- Add model-fetcher utility to query authenticated models
- Add smart-model-selector for LLM-driven model assignment
- Use session context for LLM calls during onboarding
- Suppress logging from openclaw models list calls
Documentation:
- Add prerequisites section to README
- Add conversational onboarding example
- Improve quick start flow
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Problem:
The work_start tool was automatically running a 'tick' after picking up
an issue, which filled parallel worker slots by dispatching additional
workers for other issues without explicit instruction.
Example: Picking up #123 also auto-dispatched QA for #121 via tickPickups.
Root Cause:
work_start called tickAndNotify() which ran projectTick() to fill free
worker slots in parallel execution mode. This behavior was automatic and
not controllable.
Solution:
- Disabled the auto-tick functionality in work_start
- Commented out the tickAndNotify call
- Removed tickPickups from the response
- Updated documentation to reflect the change
Impact:
- work_start now picks up ONLY the explicitly requested issue
- No automatic worker dispatch for parallel slots
- For filling worker slots, use work_heartbeat instead
- Gives more control over worker assignments
Changes:
- lib/tools/work-start.ts:
* Commented out tickAndNotify call
* Removed tickPickups from output
* Updated file header comment
* Updated tool description
Addresses issue #125
- Updated WorkerState type to use 'level' instead of 'tier'.
- Modified functions related to worker state management, including parseWorkerState, emptyWorkerState, getSessionForLevel, activateWorker, and deactivateWorker to reflect the new terminology.
- Adjusted health check logic to utilize 'level' instead of 'tier'.
- Refactored tick and setup tools to accommodate the change from 'tier' to 'level', including model configuration and workspace scaffolding.
- Updated tests to ensure consistency with the new 'level' terminology.
- Revised documentation and comments to reflect the changes in terminology from 'tier' to 'level'.
- Introduced a new heartbeat service that runs at defined intervals to perform health checks on workers and fill available task slots based on priority.
- Added a health tool to scan worker health across projects with optional auto-fix capabilities.
- Updated the status tool to provide a lightweight overview of worker states and queue counts without health checks.
- Enhanced task creation tool descriptions to clarify task state handling.
- Implemented tests for the work heartbeat logic, ensuring proper project resolution, worker state management, and task prioritization.
- Moved setup logic into dedicated files: agent.ts, config.ts, index.ts, workspace.ts.
- Introduced tool-helpers.ts for shared functions across tools, reducing boilerplate.
- Updated tools (status, task-comment, task-create, task-update, work-finish, work-start) to utilize new helper functions for workspace resolution and provider creation.
- Enhanced error handling and context detection in tools.
- Improved project resolution logic to streamline tool execution.
- Added new functionality for agent creation and configuration management in setup.
Remove hard-coded auto-chain dispatch (DEV done→QA, QA fail→DEV) and
replace with a general-purpose projectTick service that scans the queue
and fills free worker slots after every state transition.
- Create lib/services/tick.ts: consolidates shared helpers and core
projectTick() function from duplicated code in work-start/auto-pickup
- work_finish: replaces auto-chain block with projectTick call
- work_start: adds projectTick after dispatch to fill parallel slots
- auto_pickup: delegates per-project loop to projectTick
- Remove autoChain from Project type, migration code, and project-register
- Remove scheduling config dependency from work_finish
- Net -112 lines: simpler, self-healing pipeline
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Updated import paths for task management providers in task-comment, task-create, and task-update tools.
- Removed deprecated task-complete and task-pickup tools, replacing them with work-finish and work-start tools for improved task handling.
- Enhanced work-finish and work-start tools to streamline task completion and pickup processes, including context-aware detection and auto-scheduling features.
- Updated package.json to include build scripts and main entry point.
- Modified tsconfig.json to enable output directory, declaration files, and source maps for better TypeScript support.
Automatically includes the issue URL in the announcement when
task_create is called, eliminating the need for users to ask
'What's the URL?' after creating a task.
Changes:
- Enhanced announcement formatting with line breaks
- Always includes issue URL with 🔗 prefix
- Improved readability with structured format
Example output:
📋 Created #109: "Fix bug" (To Do)
🔗https://github.com/user/repo/issues/109
Ready for pickup when needed.
Example with description:
📋 Created #110: "Add feature" (Planning)
With detailed description.
🔗https://github.com/user/repo/issues/110
Picking up for DEV...
Addresses issue #109
Improvements to notification system for better traceability:
1. DEV Completion Notifications:
- Always include issue URL (📋 Issue: ...)
- Include PR/MR URL when available (🔗 PR: ...)
- Issue URL serves as fallback when PR/MR not found
- Both URLs shown when PR/MR exists for maximum traceability
2. QA Pass Notifications:
- Now include issue URL (📋 Issue: ...)
- Provides direct link to resolved issue
3. Tool Aliases:
- Added 'work_finish' as alias for 'task_complete'
- Added 'work_start' as alias for 'task_pickup'
- Added 'status' as alias for 'queue_status'
- Matches naming used in AGENTS.md documentation
Example DEV notification:
✅ DEV done #106 — Enhanced notification URLs
📋 Issue: https://github.com/user/repo/issues/106🔗 PR: https://github.com/user/repo/pull/107
Moved to QA queue.
Example QA notification:
🎉 QA PASS #106 — All tests passed
📋 Issue: https://github.com/user/repo/issues/106
Issue closed.
Addresses issue #106
Adds automatic PR/MR URL detection and inclusion in DEV completion
announcements to provide better visibility into completed work.
Changes:
1. TaskManager interface:
- Added getMergedMRUrl() method to fetch PR/MR URL for an issue
2. GitHub/GitLab providers:
- Implemented getMergedMRUrl() to find most recent merged PR/MR
- Returns URL of PR/MR that references the issue number
3. task_complete tool:
- Added optional prUrl parameter
- Auto-detects PR/MR URL if not provided
- Includes PR URL in announcement with 🔗 prefix
- Format: 'PR: https://github.com/...'
4. Role templates (dev.md):
- Updated to instruct workers to include prUrl in task_complete
- Documents that prUrl is optional (auto-detected as fallback)
Example announcement:
✅ DEV done #101 — Added PR/MR URL to notifications
🔗 PR: https://github.com/user/repo/pull/102
. Moved to QA queue.
Addresses issue #101
Adds test file with validation scenarios:
- Schema validation for required/optional params
- All 8 state labels are supported
- Same-state transitions handled gracefully
- Audit logging verification
Includes manual test scenarios for integration verification.
Addresses issue #71 acceptance criteria:
✅ Can transition any issue to any valid state
✅ Logs reason to audit trail
✅ Updates GitHub label (projects.json managed by session_health)
✅ Documented as orchestrator-only in AGENTS.md
Closes#26
This PR adds two new DevClaw tools for better task lifecycle management:
- task_update: Change issue state programmatically without full pickup/complete flow
- task_comment: Add review comments or notes to issues with optional role attribution
Adds defense-in-depth by explicitly calling activateWorker() in task_pickup.ts
after dispatchTask() returns. This ensures the worker state (active, issueId,
model, sessionKey, startTime) is properly set in projects.json even if
dispatchTask's internal state update encounters issues.
The redundant update:
- Sets active=true, issueId, and model for both spawn and reuse cases
- Sets sessionKey and startTime only on new spawns (not on session reuse)
- Provides fallback if race conditions or I/O errors affect dispatch.ts
Fixes#23
- Show plugin-level projectExecution setting in output
- Show project-level roleExecution for each project
- Sequential mode: single global task sequence across projects
- Parallel mode: per-project task tracks
- Proper handling of roleExecution within each project
- Priority ordering (To Improve > To Test > To Do)
- Visual distinction between active and upcoming tasks
Closes#21
- Add issue URL to announcement in dispatch.ts
- Add issueUrl field to workerStart notification event
- Update notification message to include URL
- Both automated notifications and manual announcements now show full ticket URL
Example output:
🔧 Spawning DEV (medior) for #7: Create TODO.md...
🔗https://github.com/laurentenhoor/devclaw/issues/7
Replaces single 'workMode' with two distinct settings:
1. Plugin-level 'projectExecution' (parallel | sequential)
- parallel: each project can have active workers independently
- sequential: only one project can have active workers at a time
2. Project-level 'roleExecution' (parallel | sequential)
- parallel: DEV and QA can run simultaneously on same project
- sequential: only one role (DEV or QA) active at a time per project
Changes:
- index.ts: rename workMode → projectExecution in config schema
- projects.ts: add roleExecution field to Project type
- heartbeat_tick: check both levels before picking up tasks
- task_pickup: enforce roleExecution when picking up manually
- project_register: accept roleExecution param (default: parallel)
- devclaw_setup: accept projectExecution param
All defaults remain 'parallel' for backward compatibility.
Adds notification system for full visibility into the DevClaw pipeline:
Events and targets:
- workerStart: Posted to project group when worker spawns/resumes
- workerComplete: Posted to project group when DEV done/QA pass/fail/refine
- heartbeat: Posted to orchestrator DM with tick summary
Implementation:
- New lib/notify.ts module with buildMessage() and sendMessage()
- Integrated into task_pickup, task_complete, and heartbeat_tick
- Uses OpenClaw gateway to invoke message tool
Configuration (optional):
- orchestratorDm: Chat ID for heartbeat notifications
- notifications.heartbeatDm: Enable/disable heartbeat DM (default: true)
- notifications.workerStart: Enable/disable start notifications (default: true)
- notifications.workerComplete: Enable/disable completion notifications (default: true)
Notifications fail silently (logged but don't break main flow).
Adds heartbeat_tick tool that automates task pickup across all projects:
- Runs session health checks (zombie cleanup) before pickups
- Loops over all registered projects
- Picks up tasks by priority (To Improve > To Test > To Do)
- Supports two work modes:
- parallel: each project can have DEV+QA running independently
- sequential: only 1 DEV + 1 QA globally (can be different projects)
- Respects per-project maxDevWorkers/maxQaWorkers settings
- Supports dryRun mode and maxPickups limit
- Context guard: only works from DM/cron, blocks project groups
Also adds:
- workMode config option (parallel | sequential)
- maxDevWorkers/maxQaWorkers fields to Project type
- projectGroupId: auto-detected from group chat context
- role: inferred from issue label (To Do/To Improve → dev, To Test → qa)
- model: detected from tier labels on issue, then falls back to heuristics
- issueId: if omitted, picks next by priority (To Improve > To Test > To Do)
All parameters are now optional. Tool includes autoDetected object in response
to indicate which values were auto-detected vs explicitly provided.
- Move resolveRepoPath to lib/utils.ts
- Update all tools to use createProvider() from lib/providers/
- Remove direct imports from lib/gitlab.ts
- Mark lib/gitlab.ts as deprecated
- All tools now work with both GitHub (gh CLI) and GitLab (glab CLI)
- Provider auto-detected from git remote URL
- Add context-guard.ts to detect interaction context (via-agent, direct, group) and generate guardrails.
- Introduce onboarding.ts for conversational onboarding context templates and workspace file checks.
- Enhance setup.ts to support new agent creation with channel binding and migration of existing bindings.
- Create analyze-channel-bindings.ts to analyze channel availability and detect binding conflicts.
- Implement context-test.ts for debugging context detection.
- Develop devclaw_onboard.ts for explicit onboarding tool that guides users through setup.
- Update devclaw_setup.ts to include channel binding and migration support in setup process.
- Modify project-register.ts to enforce project registration from group context and auto-populate group ID.
- Enhance queue-status.ts to provide context-aware status checks and recommendations.
- Update task tools (task-complete, task-create, task-pickup) to clarify group ID usage for Telegram/WhatsApp.
- Added TypeScript configuration file (tsconfig.json) with strict settings.
- Introduced devDependencies for TypeScript in package.json.
- Added scripts for type checking and watching for changes.
- Created a new types file (lib/types.ts) defining shared types for the DevClaw plugin.
- Replaced raw model aliases with developer tiers (junior, medior, senior, qa) in dispatch and model selection logic.
- Updated `dispatchTask` to resolve models based on tiers and plugin configuration.
- Modified `selectModel` to return tier names instead of model aliases based on task description.
- Implemented migration logic for transitioning from old model aliases to new tier names in worker state.
- Added setup logic for agent creation and model configuration in `setup.ts`.
- Created shared templates for workspace files and instructions for DEV/QA workers.
- Enhanced project registration to scaffold role files based on developer tiers.
- Updated task management tools to reflect changes in model selection and tier assignment.
- Introduced a new `devclaw_setup` tool for agent-driven setup and configuration.
- Updated plugin configuration schema to support model mapping per developer tier.
- Add GitLabProvider class for handling issue operations, label management, and MR checks.
- Implement methods for ensuring labels, creating issues, listing issues by label, and transitioning labels.
- Introduce a provider factory to auto-detect GitLab or GitHub based on the repository URL.
- Create project registration tool to validate repositories, create state labels, and log project entries.
- Enhance queue status and session health tools to support new session management features.
- Update task completion and task creation tools to support auto-chaining and improved session handling.
- Refactor task pickup tool to streamline model selection and session management.
Multi-project dev/qa pipeline orchestration with 4 agent tools:
- task_pickup: atomic task pickup with model selection and session reuse
- task_complete: DEV done, QA pass/fail/refine with label transitions
- queue_status: task queue and worker status across projects
- session_health: zombie detection and state consistency checks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>