feat: add host-driven GitHub Actions CI watcher (Level 3)

Replace LLM-per-tick polling with direct `gh api` calls for GitHub
Actions watchers. New `ci_provider` discriminator column routes tasks
to either the host-driven path (zero LLM tokens) or the existing
generic LLM path. GitHub watchers poll at 15s intervals (min 10s)
via `checkGitHubActionsRun()` in the scheduler, with completion
messages sent directly to chat on terminal state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Eyejoker
2026-03-25 22:31:42 +09:00
parent 07c1437055
commit 33fcf9c788
13 changed files with 841 additions and 14 deletions

View File

@@ -400,6 +400,36 @@ describe('task CRUD', () => {
expect(getTaskById('task-2')!.status).toBe('paused');
});
it('stores and updates GitHub CI task metadata', () => {
createTask({
id: 'task-github',
group_folder: 'main',
chat_jid: 'group@g.us',
ci_provider: 'github',
ci_metadata: JSON.stringify({ repo: 'owner/repo', run_id: 123456 }),
prompt: 'github watcher',
schedule_type: 'interval',
schedule_value: '15000',
context_mode: 'isolated',
next_run: '2024-06-01T00:00:00.000Z',
status: 'active',
created_at: '2024-01-01T00:00:00.000Z',
});
expect(getTaskById('task-github')?.ci_provider).toBe('github');
expect(getTaskById('task-github')?.ci_metadata).toContain('owner/repo');
updateTask('task-github', {
ci_metadata: JSON.stringify({
repo: 'owner/repo',
run_id: 123456,
poll_count: 2,
}),
});
expect(getTaskById('task-github')?.ci_metadata).toContain('"poll_count":2');
});
it('deletes a task and its run logs', () => {
createTask({
id: 'task-3',