## 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
- 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'.
Problem:
When workers were deactivated (task completed or fixed by health checks),
the startTime field was not being cleared. This caused:
- Inactive workers to retain stale timestamps
- Misleading duration data in projects.json
- Potential confusion in health checks and status displays
Example from projects.json:
{
"qa": {
"active": false,
"issueId": null,
"startTime": "2026-02-10T08:51:50.725Z", // Stale!
"tier": "qa"
}
}
Root Cause:
The deactivateWorker() function only set active: false and issueId: null,
but did not clear startTime. Similarly, health check auto-fixes that
deactivated workers also failed to clear startTime.
Solution:
Always set startTime: null when deactivating a worker to ensure clean state.
Changes:
1. lib/projects.ts:
- deactivateWorker() now sets startTime: null
- Updated function comment to document this behavior
2. lib/services/health.ts:
- All three auto-fix paths that deactivate workers now clear startTime:
* active_no_session fix (line 77)
* zombie_session fix (line 98)
* stale_worker fix (line 138)
Impact:
- Inactive workers now have clean state (startTime: null)
- Duration calculations only apply to active workers
- Health checks work with accurate data
- No stale timestamps persisting across task completions
- Complements fix from #108 (which ensures startTime is set on activation)
Together with #108:
- #108: Always SET startTime when activating worker
- #113: Always CLEAR startTime when deactivating worker
- Result: startTime accurately reflects current task duration
Addresses issue #113
- 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.
- 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.