devchain-cli 0.2.2 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/drizzle/0018_whole_zodiak.sql +43 -0
- package/dist/drizzle/0019_flat_avengers.sql +3 -0
- package/dist/drizzle/0020_statuses_mcp_hidden.sql +1 -0
- package/dist/drizzle/meta/0018_snapshot.json +2920 -0
- package/dist/drizzle/meta/0019_snapshot.json +2943 -0
- package/dist/drizzle/meta/0020_snapshot.json +2951 -0
- package/dist/drizzle/meta/_journal.json +21 -0
- package/dist/server/app.module.js +11 -1
- package/dist/server/app.module.js.map +1 -1
- package/dist/server/common/config/env.config.d.ts +1 -0
- package/dist/server/common/config/env.config.js +4 -0
- package/dist/server/common/config/env.config.js.map +1 -1
- package/dist/server/common/filters/http-exception.filter.js +24 -1
- package/dist/server/common/filters/http-exception.filter.js.map +1 -1
- package/dist/server/common/logging/logger.js +4 -3
- package/dist/server/common/logging/logger.js.map +1 -1
- package/dist/server/main.js +0 -3
- package/dist/server/main.js.map +1 -1
- package/dist/server/modules/agents/agents.module.js +2 -1
- package/dist/server/modules/agents/agents.module.js.map +1 -1
- package/dist/server/modules/agents/controllers/agents.controller.d.ts +17 -2
- package/dist/server/modules/agents/controllers/agents.controller.js +84 -3
- package/dist/server/modules/agents/controllers/agents.controller.js.map +1 -1
- package/dist/server/modules/chat/dtos/chat.dto.d.ts +18 -18
- package/dist/server/modules/chat/services/invite-template.util.js +1 -1
- package/dist/server/modules/chat/services/invite-template.util.js.map +1 -1
- package/dist/server/modules/events/catalog/index.d.ts +40 -0
- package/dist/server/modules/events/catalog/index.js +2 -0
- package/dist/server/modules/events/catalog/index.js.map +1 -1
- package/dist/server/modules/events/catalog/terminal.watcher.triggered.d.ts +45 -0
- package/dist/server/modules/events/catalog/terminal.watcher.triggered.js +22 -0
- package/dist/server/modules/events/catalog/terminal.watcher.triggered.js.map +1 -0
- package/dist/server/modules/events/subscribers/chat-message-delivery.subscriber.d.ts +1 -0
- package/dist/server/modules/events/subscribers/chat-message-delivery.subscriber.js +30 -12
- package/dist/server/modules/events/subscribers/chat-message-delivery.subscriber.js.map +1 -1
- package/dist/server/modules/mcp/constants.js +5 -1
- package/dist/server/modules/mcp/constants.js.map +1 -1
- package/dist/server/modules/mcp/controllers/mcp-http.controller.js +78 -77
- package/dist/server/modules/mcp/controllers/mcp-http.controller.js.map +1 -1
- package/dist/server/modules/mcp/controllers/mcp-sdk.controller.js +78 -77
- package/dist/server/modules/mcp/controllers/mcp-sdk.controller.js.map +1 -1
- package/dist/server/modules/mcp/dtos/mcp.dto.d.ts +125 -97
- package/dist/server/modules/mcp/dtos/mcp.dto.js +23 -26
- package/dist/server/modules/mcp/dtos/mcp.dto.js.map +1 -1
- package/dist/server/modules/mcp/services/instructions-resolver.d.ts +3 -0
- package/dist/server/modules/mcp/services/instructions-resolver.js +83 -2
- package/dist/server/modules/mcp/services/instructions-resolver.js.map +1 -1
- package/dist/server/modules/mcp/services/mcp.service.d.ts +3 -2
- package/dist/server/modules/mcp/services/mcp.service.js +549 -263
- package/dist/server/modules/mcp/services/mcp.service.js.map +1 -1
- package/dist/server/modules/projects/controllers/projects.controller.d.ts +41 -0
- package/dist/server/modules/projects/projects.module.js +2 -1
- package/dist/server/modules/projects/projects.module.js.map +1 -1
- package/dist/server/modules/projects/services/projects.service.d.ts +46 -1
- package/dist/server/modules/projects/services/projects.service.js +243 -18
- package/dist/server/modules/projects/services/projects.service.js.map +1 -1
- package/dist/server/modules/prompts/controllers/prompts.controller.d.ts +1 -1
- package/dist/server/modules/prompts/controllers/prompts.controller.js +26 -4
- package/dist/server/modules/prompts/controllers/prompts.controller.js.map +1 -1
- package/dist/server/modules/sessions/utils/template-renderer.js +1 -0
- package/dist/server/modules/sessions/utils/template-renderer.js.map +1 -1
- package/dist/server/modules/statuses/controllers/statuses.controller.js +2 -0
- package/dist/server/modules/statuses/controllers/statuses.controller.js.map +1 -1
- package/dist/server/modules/storage/db/schema.d.ts +613 -0
- package/dist/server/modules/storage/db/schema.js +50 -1
- package/dist/server/modules/storage/db/schema.js.map +1 -1
- package/dist/server/modules/storage/interfaces/storage.interface.d.ts +40 -2
- package/dist/server/modules/storage/interfaces/storage.interface.js.map +1 -1
- package/dist/server/modules/storage/local/local-storage.service.d.ts +18 -3
- package/dist/server/modules/storage/local/local-storage.service.js +407 -11
- package/dist/server/modules/storage/local/local-storage.service.js.map +1 -1
- package/dist/server/modules/storage/models/domain.models.d.ts +59 -1
- package/dist/server/modules/subscribers/actions/action.interface.d.ts +67 -0
- package/dist/server/modules/subscribers/actions/action.interface.js +3 -0
- package/dist/server/modules/subscribers/actions/action.interface.js.map +1 -0
- package/dist/server/modules/subscribers/actions/actions.registry.d.ts +7 -0
- package/dist/server/modules/subscribers/actions/actions.registry.js +37 -0
- package/dist/server/modules/subscribers/actions/actions.registry.js.map +1 -0
- package/dist/server/modules/subscribers/actions/restart-agent.action.d.ts +8 -0
- package/dist/server/modules/subscribers/actions/restart-agent.action.js +119 -0
- package/dist/server/modules/subscribers/actions/restart-agent.action.js.map +1 -0
- package/dist/server/modules/subscribers/actions/send-message.action.d.ts +2 -0
- package/dist/server/modules/subscribers/actions/send-message.action.js +83 -0
- package/dist/server/modules/subscribers/actions/send-message.action.js.map +1 -0
- package/dist/server/modules/subscribers/controllers/actions.controller.d.ts +6 -0
- package/dist/server/modules/subscribers/controllers/actions.controller.js +51 -0
- package/dist/server/modules/subscribers/controllers/actions.controller.js.map +1 -0
- package/dist/server/modules/subscribers/controllers/subscribers.controller.d.ts +17 -0
- package/dist/server/modules/subscribers/controllers/subscribers.controller.js +178 -0
- package/dist/server/modules/subscribers/controllers/subscribers.controller.js.map +1 -0
- package/dist/server/modules/subscribers/dtos/subscriber.dto.d.ts +251 -0
- package/dist/server/modules/subscribers/dtos/subscriber.dto.js +68 -0
- package/dist/server/modules/subscribers/dtos/subscriber.dto.js.map +1 -0
- package/dist/server/modules/subscribers/events/event-fields-catalog.d.ts +19 -0
- package/dist/server/modules/subscribers/events/event-fields-catalog.js +98 -0
- package/dist/server/modules/subscribers/events/event-fields-catalog.js.map +1 -0
- package/dist/server/modules/subscribers/services/automation-scheduler.service.d.ts +49 -0
- package/dist/server/modules/subscribers/services/automation-scheduler.service.js +300 -0
- package/dist/server/modules/subscribers/services/automation-scheduler.service.js.map +1 -0
- package/dist/server/modules/subscribers/services/subscriber-executor.service.d.ts +77 -0
- package/dist/server/modules/subscribers/services/subscriber-executor.service.js +576 -0
- package/dist/server/modules/subscribers/services/subscriber-executor.service.js.map +1 -0
- package/dist/server/modules/subscribers/services/subscribers.service.d.ts +14 -0
- package/dist/server/modules/subscribers/services/subscribers.service.js +70 -0
- package/dist/server/modules/subscribers/services/subscribers.service.js.map +1 -0
- package/dist/server/modules/subscribers/subscribers.module.d.ts +2 -0
- package/dist/server/modules/subscribers/subscribers.module.js +36 -0
- package/dist/server/modules/subscribers/subscribers.module.js.map +1 -0
- package/dist/server/modules/terminal/services/tmux.service.js +9 -6
- package/dist/server/modules/terminal/services/tmux.service.js.map +1 -1
- package/dist/server/modules/watchers/controllers/watchers.controller.d.ts +16 -0
- package/dist/server/modules/watchers/controllers/watchers.controller.js +180 -0
- package/dist/server/modules/watchers/controllers/watchers.controller.js.map +1 -0
- package/dist/server/modules/watchers/dtos/watcher.dto.d.ts +206 -0
- package/dist/server/modules/watchers/dtos/watcher.dto.js +54 -0
- package/dist/server/modules/watchers/dtos/watcher.dto.js.map +1 -0
- package/dist/server/modules/watchers/services/watcher-runner.service.d.ts +68 -0
- package/dist/server/modules/watchers/services/watcher-runner.service.js +477 -0
- package/dist/server/modules/watchers/services/watcher-runner.service.js.map +1 -0
- package/dist/server/modules/watchers/services/watchers.service.d.ts +29 -0
- package/dist/server/modules/watchers/services/watchers.service.js +98 -0
- package/dist/server/modules/watchers/services/watchers.service.js.map +1 -0
- package/dist/server/modules/watchers/watchers.module.d.ts +2 -0
- package/dist/server/modules/watchers/watchers.module.js +34 -0
- package/dist/server/modules/watchers/watchers.module.js.map +1 -0
- package/dist/server/templates/claude-codex-advanced.json +377 -0
- package/dist/server/templates/claude-opus.json +29 -25
- package/dist/server/templates/simple-codex.json +29 -25
- package/dist/server/test-setup-node.d.ts +1 -0
- package/dist/server/test-setup-node.js +8 -0
- package/dist/server/test-setup-node.js.map +1 -0
- package/dist/server/test-setup.js +2 -0
- package/dist/server/test-setup.js.map +1 -1
- package/dist/server/tsconfig.tsbuildinfo +1 -1
- package/dist/server/ui/assets/index-C9GXCjnF.js +700 -0
- package/dist/server/ui/assets/index-o0FbZg-1.css +32 -0
- package/dist/server/ui/index.html +2 -2
- package/dist/templates/claude-codex-advanced.json +377 -0
- package/dist/templates/claude-opus.json +29 -25
- package/dist/templates/simple-codex.json +29 -25
- package/package.json +41 -27
- package/dist/server/templates/codex-claude.json +0 -178
- package/dist/server/ui/assets/index-CbYIbCQV.css +0 -32
- package/dist/server/ui/assets/index-sfYpjMjv.js +0 -641
- package/dist/templates/codex-claude.json +0 -178
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ToggleWatcherSchema = exports.UpdateWatcherSchema = exports.CreateWatcherSchema = exports.TriggerConditionSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.TriggerConditionSchema = zod_1.z.object({
|
|
6
|
+
type: zod_1.z.enum(['contains', 'regex', 'not_contains']),
|
|
7
|
+
pattern: zod_1.z.string().min(1).max(1000),
|
|
8
|
+
flags: zod_1.z.string().max(10).optional(),
|
|
9
|
+
});
|
|
10
|
+
exports.CreateWatcherSchema = zod_1.z
|
|
11
|
+
.object({
|
|
12
|
+
projectId: zod_1.z.string().uuid(),
|
|
13
|
+
name: zod_1.z.string().min(1).max(100),
|
|
14
|
+
description: zod_1.z.string().max(500).optional(),
|
|
15
|
+
enabled: zod_1.z.boolean().optional().default(true),
|
|
16
|
+
scope: zod_1.z.enum(['all', 'agent', 'profile', 'provider']).optional().default('all'),
|
|
17
|
+
scopeFilterId: zod_1.z.string().min(1).max(200).optional().nullable(),
|
|
18
|
+
pollIntervalMs: zod_1.z.number().int().min(1000).max(60000).optional().default(5000),
|
|
19
|
+
viewportLines: zod_1.z.number().int().min(10).max(200).optional().default(50),
|
|
20
|
+
condition: exports.TriggerConditionSchema,
|
|
21
|
+
cooldownMs: zod_1.z.number().int().min(0).max(3600000).optional().default(60000),
|
|
22
|
+
cooldownMode: zod_1.z.enum(['time', 'until_clear']).optional().default('time'),
|
|
23
|
+
eventName: zod_1.z
|
|
24
|
+
.string()
|
|
25
|
+
.min(1)
|
|
26
|
+
.max(100)
|
|
27
|
+
.regex(/^[a-z][a-z0-9._-]*$/i, 'Event name must start with letter, contain only letters, numbers, dots, underscores, hyphens'),
|
|
28
|
+
})
|
|
29
|
+
.refine((data) => data.scope === 'all' || !!data.scopeFilterId, {
|
|
30
|
+
message: 'scopeFilterId is required when scope is not "all"',
|
|
31
|
+
path: ['scopeFilterId'],
|
|
32
|
+
});
|
|
33
|
+
exports.UpdateWatcherSchema = zod_1.z.object({
|
|
34
|
+
name: zod_1.z.string().min(1).max(100).optional(),
|
|
35
|
+
description: zod_1.z.string().max(500).optional().nullable(),
|
|
36
|
+
enabled: zod_1.z.boolean().optional(),
|
|
37
|
+
scope: zod_1.z.enum(['all', 'agent', 'profile', 'provider']).optional(),
|
|
38
|
+
scopeFilterId: zod_1.z.string().min(1).max(200).optional().nullable(),
|
|
39
|
+
pollIntervalMs: zod_1.z.number().int().min(1000).max(60000).optional(),
|
|
40
|
+
viewportLines: zod_1.z.number().int().min(10).max(200).optional(),
|
|
41
|
+
condition: exports.TriggerConditionSchema.optional(),
|
|
42
|
+
cooldownMs: zod_1.z.number().int().min(0).max(3600000).optional(),
|
|
43
|
+
cooldownMode: zod_1.z.enum(['time', 'until_clear']).optional(),
|
|
44
|
+
eventName: zod_1.z
|
|
45
|
+
.string()
|
|
46
|
+
.min(1)
|
|
47
|
+
.max(100)
|
|
48
|
+
.regex(/^[a-z][a-z0-9._-]*$/i, 'Event name must start with letter, contain only letters, numbers, dots, underscores, hyphens')
|
|
49
|
+
.optional(),
|
|
50
|
+
});
|
|
51
|
+
exports.ToggleWatcherSchema = zod_1.z.object({
|
|
52
|
+
enabled: zod_1.z.boolean(),
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=watcher.dto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.dto.js","sourceRoot":"","sources":["../../../../src/modules/watchers/dtos/watcher.dto.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAUX,QAAA,sBAAsB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC7C,IAAI,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;IACnD,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IACpC,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;CACrC,CAAC,CAAC;AAQU,QAAA,mBAAmB,GAAG,OAAC;KACjC,MAAM,CAAC;IACN,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC5B,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAChC,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC3C,OAAO,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC7C,KAAK,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAGhF,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC/D,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9E,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACvE,SAAS,EAAE,8BAAsB;IACjC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC1E,YAAY,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;IACxE,SAAS,EAAE,OAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,KAAK,CACJ,sBAAsB,EACtB,8FAA8F,CAC/F;CACJ,CAAC;KACD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE;IAC9D,OAAO,EAAE,mDAAmD;IAC5D,IAAI,EAAE,CAAC,eAAe,CAAC;CACxB,CAAC,CAAC;AASQ,QAAA,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1C,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC3C,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACtD,OAAO,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC/B,KAAK,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE;IACjE,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC/D,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE;IAChE,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC3D,SAAS,EAAE,8BAAsB,CAAC,QAAQ,EAAE;IAC5C,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE;IAC3D,YAAY,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,EAAE;IACxD,SAAS,EAAE,OAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,KAAK,CACJ,sBAAsB,EACtB,8FAA8F,CAC/F;SACA,QAAQ,EAAE;CACd,CAAC,CAAC;AAQU,QAAA,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1C,OAAO,EAAE,OAAC,CAAC,OAAO,EAAE;CACrB,CAAC,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
|
2
|
+
import { type StorageService } from '../../storage/interfaces/storage.interface';
|
|
3
|
+
import type { Watcher, TriggerCondition } from '../../storage/models/domain.models';
|
|
4
|
+
import { SessionsService } from '../../sessions/services/sessions.service';
|
|
5
|
+
import { TmuxService } from '../../terminal/services/tmux.service';
|
|
6
|
+
import { EventsService } from '../../events/services/events.service';
|
|
7
|
+
import type { SessionDto } from '../../sessions/dtos/sessions.dto';
|
|
8
|
+
export declare class WatcherRunnerService implements OnModuleInit, OnModuleDestroy {
|
|
9
|
+
private readonly storage;
|
|
10
|
+
private readonly sessionsService;
|
|
11
|
+
private readonly tmuxService;
|
|
12
|
+
private readonly eventsService;
|
|
13
|
+
private readonly logger;
|
|
14
|
+
private readonly pollIntervals;
|
|
15
|
+
private readonly cooldowns;
|
|
16
|
+
private readonly lastConditionState;
|
|
17
|
+
private readonly lastTriggeredHash;
|
|
18
|
+
private readonly triggerCounts;
|
|
19
|
+
private readonly captureCache;
|
|
20
|
+
private readonly inFlight;
|
|
21
|
+
private readonly watcherConfigs;
|
|
22
|
+
constructor(storage: StorageService, sessionsService: SessionsService, tmuxService: TmuxService, eventsService: EventsService);
|
|
23
|
+
onModuleInit(): Promise<void>;
|
|
24
|
+
onModuleDestroy(): Promise<void>;
|
|
25
|
+
startWatcher(watcher: Watcher): Promise<void>;
|
|
26
|
+
startWatcher(watcherId: string): Promise<void>;
|
|
27
|
+
stopWatcher(watcherId: string): Promise<void>;
|
|
28
|
+
restartWatcher(watcherId: string): Promise<void>;
|
|
29
|
+
private pollWatcher;
|
|
30
|
+
checkSession(watcher: Watcher, session: SessionDto): Promise<{
|
|
31
|
+
skipped: boolean;
|
|
32
|
+
reason?: string;
|
|
33
|
+
matched?: boolean;
|
|
34
|
+
triggered?: boolean;
|
|
35
|
+
viewportHash?: string;
|
|
36
|
+
}>;
|
|
37
|
+
triggerEvent(watcher: Watcher, session: SessionDto, viewport: string, viewportHash: string, triggerCount: number): Promise<void>;
|
|
38
|
+
getMatchingSessions(watcher: Watcher): Promise<SessionDto[]>;
|
|
39
|
+
captureViewport(tmuxSessionId: string, lines: number): Promise<string>;
|
|
40
|
+
getCachedCapture(tmuxSessionId: string, lines: number): string | null;
|
|
41
|
+
setCachedCapture(tmuxSessionId: string, lines: number, text: string): void;
|
|
42
|
+
clearCaptureCache(): void;
|
|
43
|
+
matchCondition(condition: TriggerCondition, text: string): boolean;
|
|
44
|
+
isOnCooldown(watcherId: string, sessionId: string): boolean;
|
|
45
|
+
setCooldown(watcherId: string, sessionId: string, durationMs: number): void;
|
|
46
|
+
clearCooldown(watcherId: string, sessionId: string): void;
|
|
47
|
+
computeViewportHash(viewport: string): string;
|
|
48
|
+
checkTriggerEligibility(watcher: Watcher, sessionId: string, viewport: string, conditionMatched: boolean): {
|
|
49
|
+
shouldTrigger: boolean;
|
|
50
|
+
viewportHash: string;
|
|
51
|
+
};
|
|
52
|
+
getLastConditionState(watcherId: string, sessionId: string): boolean | undefined;
|
|
53
|
+
setLastConditionState(watcherId: string, sessionId: string, matched: boolean): void;
|
|
54
|
+
getLastTriggeredHash(watcherId: string, sessionId: string): string | undefined;
|
|
55
|
+
setLastTriggeredHash(watcherId: string, sessionId: string, hash: string): void;
|
|
56
|
+
incrementTriggerCount(watcherId: string, sessionId: string): number;
|
|
57
|
+
getTriggerCount(watcherId: string, sessionId: string): number;
|
|
58
|
+
isWatcherRunning(watcherId: string): boolean;
|
|
59
|
+
getRunningWatcherIds(): string[];
|
|
60
|
+
testWatcher(watcher: Watcher): Promise<Array<{
|
|
61
|
+
sessionId: string;
|
|
62
|
+
agentId: string | null;
|
|
63
|
+
tmuxSessionId: string | null;
|
|
64
|
+
viewport: string | null;
|
|
65
|
+
viewportHash: string | null;
|
|
66
|
+
conditionMatched: boolean;
|
|
67
|
+
}>>;
|
|
68
|
+
}
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.WatcherRunnerService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const crypto_1 = require("crypto");
|
|
18
|
+
const logger_1 = require("../../../common/logging/logger");
|
|
19
|
+
const storage_interface_1 = require("../../storage/interfaces/storage.interface");
|
|
20
|
+
const sessions_service_1 = require("../../sessions/services/sessions.service");
|
|
21
|
+
const tmux_service_1 = require("../../terminal/services/tmux.service");
|
|
22
|
+
const events_service_1 = require("../../events/services/events.service");
|
|
23
|
+
const CAPTURE_TTL_MS = 2000;
|
|
24
|
+
let WatcherRunnerService = class WatcherRunnerService {
|
|
25
|
+
constructor(storage, sessionsService, tmuxService, eventsService) {
|
|
26
|
+
this.storage = storage;
|
|
27
|
+
this.sessionsService = sessionsService;
|
|
28
|
+
this.tmuxService = tmuxService;
|
|
29
|
+
this.eventsService = eventsService;
|
|
30
|
+
this.logger = (0, logger_1.createLogger)('WatcherRunnerService');
|
|
31
|
+
this.pollIntervals = new Map();
|
|
32
|
+
this.cooldowns = new Map();
|
|
33
|
+
this.lastConditionState = new Map();
|
|
34
|
+
this.lastTriggeredHash = new Map();
|
|
35
|
+
this.triggerCounts = new Map();
|
|
36
|
+
this.captureCache = new Map();
|
|
37
|
+
this.inFlight = new Set();
|
|
38
|
+
this.watcherConfigs = new Map();
|
|
39
|
+
}
|
|
40
|
+
async onModuleInit() {
|
|
41
|
+
this.logger.info('WatcherRunnerService initializing...');
|
|
42
|
+
try {
|
|
43
|
+
const enabledWatchers = await this.storage.listEnabledWatchers();
|
|
44
|
+
this.logger.info(`Found ${enabledWatchers.length} enabled watcher(s)`);
|
|
45
|
+
for (const watcher of enabledWatchers) {
|
|
46
|
+
await this.startWatcher(watcher);
|
|
47
|
+
}
|
|
48
|
+
this.logger.info('WatcherRunnerService initialized successfully');
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
this.logger.error({ error }, 'Failed to initialize WatcherRunnerService');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async onModuleDestroy() {
|
|
55
|
+
this.logger.info('WatcherRunnerService shutting down...');
|
|
56
|
+
for (const [watcherId, interval] of this.pollIntervals) {
|
|
57
|
+
clearInterval(interval);
|
|
58
|
+
this.logger.debug({ watcherId }, 'Cleared interval');
|
|
59
|
+
}
|
|
60
|
+
this.pollIntervals.clear();
|
|
61
|
+
this.cooldowns.clear();
|
|
62
|
+
this.lastConditionState.clear();
|
|
63
|
+
this.lastTriggeredHash.clear();
|
|
64
|
+
this.triggerCounts.clear();
|
|
65
|
+
this.captureCache.clear();
|
|
66
|
+
this.inFlight.clear();
|
|
67
|
+
this.watcherConfigs.clear();
|
|
68
|
+
this.logger.info('WatcherRunnerService destroyed');
|
|
69
|
+
}
|
|
70
|
+
async startWatcher(watcherOrId) {
|
|
71
|
+
let watcher;
|
|
72
|
+
if (typeof watcherOrId === 'string') {
|
|
73
|
+
watcher = await this.storage.getWatcher(watcherOrId);
|
|
74
|
+
if (!watcher) {
|
|
75
|
+
this.logger.warn({ watcherId: watcherOrId }, 'Cannot start watcher: not found');
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
watcher = watcherOrId;
|
|
81
|
+
}
|
|
82
|
+
const watcherId = watcher.id;
|
|
83
|
+
if (this.pollIntervals.has(watcherId)) {
|
|
84
|
+
await this.stopWatcher(watcherId);
|
|
85
|
+
}
|
|
86
|
+
this.watcherConfigs.set(watcherId, watcher);
|
|
87
|
+
const interval = setInterval(() => {
|
|
88
|
+
this.pollWatcher(watcherId).catch((err) => {
|
|
89
|
+
this.logger.error({ watcherId, error: err }, 'Error in watcher poll cycle');
|
|
90
|
+
});
|
|
91
|
+
}, watcher.pollIntervalMs);
|
|
92
|
+
this.pollIntervals.set(watcherId, interval);
|
|
93
|
+
this.logger.info({
|
|
94
|
+
watcherId,
|
|
95
|
+
name: watcher.name,
|
|
96
|
+
pollIntervalMs: watcher.pollIntervalMs,
|
|
97
|
+
scope: watcher.scope,
|
|
98
|
+
}, 'Started watcher');
|
|
99
|
+
}
|
|
100
|
+
async stopWatcher(watcherId) {
|
|
101
|
+
const interval = this.pollIntervals.get(watcherId);
|
|
102
|
+
if (interval) {
|
|
103
|
+
clearInterval(interval);
|
|
104
|
+
this.pollIntervals.delete(watcherId);
|
|
105
|
+
}
|
|
106
|
+
const prefix = `${watcherId}:`;
|
|
107
|
+
for (const key of [...this.cooldowns.keys()]) {
|
|
108
|
+
if (key.startsWith(prefix)) {
|
|
109
|
+
this.cooldowns.delete(key);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
for (const key of [...this.lastConditionState.keys()]) {
|
|
113
|
+
if (key.startsWith(prefix)) {
|
|
114
|
+
this.lastConditionState.delete(key);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
for (const key of [...this.lastTriggeredHash.keys()]) {
|
|
118
|
+
if (key.startsWith(prefix)) {
|
|
119
|
+
this.lastTriggeredHash.delete(key);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const key of [...this.triggerCounts.keys()]) {
|
|
123
|
+
if (key.startsWith(prefix)) {
|
|
124
|
+
this.triggerCounts.delete(key);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
this.inFlight.delete(watcherId);
|
|
128
|
+
this.watcherConfigs.delete(watcherId);
|
|
129
|
+
this.logger.info({ watcherId }, 'Stopped watcher');
|
|
130
|
+
}
|
|
131
|
+
async restartWatcher(watcherId) {
|
|
132
|
+
this.logger.debug({ watcherId }, 'Restarting watcher');
|
|
133
|
+
await this.stopWatcher(watcherId);
|
|
134
|
+
const watcher = await this.storage.getWatcher(watcherId);
|
|
135
|
+
if (watcher && watcher.enabled) {
|
|
136
|
+
await this.startWatcher(watcher);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async pollWatcher(watcherId) {
|
|
140
|
+
if (this.inFlight.has(watcherId)) {
|
|
141
|
+
this.logger.debug({ watcherId }, 'Poll skipped: already in flight');
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const watcher = this.watcherConfigs.get(watcherId);
|
|
145
|
+
if (!watcher) {
|
|
146
|
+
this.logger.warn({ watcherId }, 'Poll skipped: watcher config not found');
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this.inFlight.add(watcherId);
|
|
150
|
+
try {
|
|
151
|
+
const sessions = await this.getMatchingSessions(watcher);
|
|
152
|
+
this.logger.debug({ watcherId, name: watcher.name, sessionCount: sessions.length }, 'Poll cycle starting');
|
|
153
|
+
for (const session of sessions) {
|
|
154
|
+
try {
|
|
155
|
+
await this.checkSession(watcher, session);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
this.logger.error({ watcherId, sessionId: session.id, error: String(error) }, 'Error checking session');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
this.inFlight.delete(watcherId);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async checkSession(watcher, session) {
|
|
167
|
+
const watcherId = watcher.id;
|
|
168
|
+
const sessionId = session.id;
|
|
169
|
+
if (!session.tmuxSessionId) {
|
|
170
|
+
this.logger.debug({ watcherId, sessionId }, 'Session skipped: no tmuxSessionId');
|
|
171
|
+
return { skipped: true, reason: 'no_tmux_session' };
|
|
172
|
+
}
|
|
173
|
+
const viewport = await this.captureViewport(session.tmuxSessionId, watcher.viewportLines);
|
|
174
|
+
if (!viewport) {
|
|
175
|
+
this.logger.debug({ watcherId, sessionId, tmuxSessionId: session.tmuxSessionId }, 'Session skipped: empty viewport');
|
|
176
|
+
return { skipped: true, reason: 'empty_viewport' };
|
|
177
|
+
}
|
|
178
|
+
const conditionMatched = this.matchCondition(watcher.condition, viewport);
|
|
179
|
+
const { shouldTrigger, viewportHash } = this.checkTriggerEligibility(watcher, sessionId, viewport, conditionMatched);
|
|
180
|
+
if (shouldTrigger) {
|
|
181
|
+
const triggerCount = this.incrementTriggerCount(watcherId, sessionId);
|
|
182
|
+
this.logger.info({
|
|
183
|
+
watcherId,
|
|
184
|
+
watcherName: watcher.name,
|
|
185
|
+
sessionId,
|
|
186
|
+
agentId: session.agentId,
|
|
187
|
+
triggerCount,
|
|
188
|
+
viewportHash,
|
|
189
|
+
}, 'Watcher triggered');
|
|
190
|
+
await this.triggerEvent(watcher, session, viewport, viewportHash, triggerCount);
|
|
191
|
+
return { skipped: false, matched: conditionMatched, triggered: true, viewportHash };
|
|
192
|
+
}
|
|
193
|
+
return { skipped: false, matched: conditionMatched, triggered: false, viewportHash };
|
|
194
|
+
}
|
|
195
|
+
async triggerEvent(watcher, session, viewport, viewportHash, triggerCount) {
|
|
196
|
+
const agent = session.agentId ? await this.storage.getAgent(session.agentId) : null;
|
|
197
|
+
const payload = {
|
|
198
|
+
watcherId: watcher.id,
|
|
199
|
+
watcherName: watcher.name,
|
|
200
|
+
customEventName: watcher.eventName,
|
|
201
|
+
sessionId: session.id,
|
|
202
|
+
agentId: session.agentId ?? null,
|
|
203
|
+
agentName: agent?.name ?? null,
|
|
204
|
+
projectId: watcher.projectId,
|
|
205
|
+
viewportSnippet: viewport.slice(-500),
|
|
206
|
+
viewportHash,
|
|
207
|
+
matchedPattern: watcher.condition.pattern,
|
|
208
|
+
triggerCount,
|
|
209
|
+
triggeredAt: new Date().toISOString(),
|
|
210
|
+
};
|
|
211
|
+
await this.eventsService.publish('terminal.watcher.triggered', payload);
|
|
212
|
+
this.logger.info({
|
|
213
|
+
watcherId: watcher.id,
|
|
214
|
+
watcherName: watcher.name,
|
|
215
|
+
customEventName: watcher.eventName,
|
|
216
|
+
sessionId: session.id,
|
|
217
|
+
agentId: session.agentId,
|
|
218
|
+
triggerCount,
|
|
219
|
+
}, 'Published watcher triggered event');
|
|
220
|
+
}
|
|
221
|
+
async getMatchingSessions(watcher) {
|
|
222
|
+
const allSessions = await this.sessionsService.listActiveSessions(watcher.projectId);
|
|
223
|
+
switch (watcher.scope) {
|
|
224
|
+
case 'all':
|
|
225
|
+
return allSessions;
|
|
226
|
+
case 'agent':
|
|
227
|
+
return allSessions.filter((session) => session.agentId && session.agentId === watcher.scopeFilterId);
|
|
228
|
+
case 'profile': {
|
|
229
|
+
const agents = await this.storage.listAgents(watcher.projectId);
|
|
230
|
+
const matchingAgentIds = new Set(agents.items
|
|
231
|
+
.filter((agent) => agent.profileId === watcher.scopeFilterId)
|
|
232
|
+
.map((agent) => agent.id));
|
|
233
|
+
return allSessions.filter((session) => session.agentId && matchingAgentIds.has(session.agentId));
|
|
234
|
+
}
|
|
235
|
+
case 'provider': {
|
|
236
|
+
const agents = await this.storage.listAgents(watcher.projectId);
|
|
237
|
+
const profileProviderCache = new Map();
|
|
238
|
+
const matchingAgentIds = new Set();
|
|
239
|
+
for (const agent of agents.items) {
|
|
240
|
+
let providerId = profileProviderCache.get(agent.profileId);
|
|
241
|
+
if (providerId === undefined) {
|
|
242
|
+
try {
|
|
243
|
+
const profile = await this.storage.getAgentProfile(agent.profileId);
|
|
244
|
+
providerId = profile.providerId;
|
|
245
|
+
profileProviderCache.set(agent.profileId, providerId);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
if (providerId === watcher.scopeFilterId) {
|
|
252
|
+
matchingAgentIds.add(agent.id);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return allSessions.filter((session) => session.agentId && matchingAgentIds.has(session.agentId));
|
|
256
|
+
}
|
|
257
|
+
default:
|
|
258
|
+
this.logger.warn({ watcherId: watcher.id, scope: watcher.scope }, 'Unknown watcher scope');
|
|
259
|
+
return [];
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
async captureViewport(tmuxSessionId, lines) {
|
|
263
|
+
const key = `${tmuxSessionId}:${lines}`;
|
|
264
|
+
const cached = this.captureCache.get(key);
|
|
265
|
+
if (cached) {
|
|
266
|
+
const age = Date.now() - cached.ts;
|
|
267
|
+
if (age < CAPTURE_TTL_MS) {
|
|
268
|
+
this.logger.debug({ tmuxSessionId, lines, cacheAge: age }, 'Cache hit for viewport capture');
|
|
269
|
+
return cached.text;
|
|
270
|
+
}
|
|
271
|
+
this.captureCache.delete(key);
|
|
272
|
+
}
|
|
273
|
+
this.logger.debug({ tmuxSessionId, lines }, 'Cache miss, capturing viewport from tmux');
|
|
274
|
+
try {
|
|
275
|
+
const text = await this.tmuxService.capturePane(tmuxSessionId, lines, false);
|
|
276
|
+
this.captureCache.set(key, { text, ts: Date.now() });
|
|
277
|
+
return text;
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
this.logger.warn({ tmuxSessionId, lines, error }, 'Failed to capture viewport from tmux');
|
|
281
|
+
return '';
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
getCachedCapture(tmuxSessionId, lines) {
|
|
285
|
+
const key = `${tmuxSessionId}:${lines}`;
|
|
286
|
+
const cached = this.captureCache.get(key);
|
|
287
|
+
if (!cached) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
const age = Date.now() - cached.ts;
|
|
291
|
+
if (age > CAPTURE_TTL_MS) {
|
|
292
|
+
this.captureCache.delete(key);
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
return cached.text;
|
|
296
|
+
}
|
|
297
|
+
setCachedCapture(tmuxSessionId, lines, text) {
|
|
298
|
+
const key = `${tmuxSessionId}:${lines}`;
|
|
299
|
+
this.captureCache.set(key, { text, ts: Date.now() });
|
|
300
|
+
}
|
|
301
|
+
clearCaptureCache() {
|
|
302
|
+
this.captureCache.clear();
|
|
303
|
+
}
|
|
304
|
+
matchCondition(condition, text) {
|
|
305
|
+
try {
|
|
306
|
+
switch (condition.type) {
|
|
307
|
+
case 'contains':
|
|
308
|
+
return text.includes(condition.pattern);
|
|
309
|
+
case 'regex': {
|
|
310
|
+
const regex = new RegExp(condition.pattern, condition.flags || '');
|
|
311
|
+
return regex.test(text);
|
|
312
|
+
}
|
|
313
|
+
case 'not_contains':
|
|
314
|
+
return !text.includes(condition.pattern);
|
|
315
|
+
default:
|
|
316
|
+
this.logger.warn({ conditionType: condition.type }, 'Unknown condition type in matchCondition');
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
this.logger.error({ condition, error: String(error) }, 'Error in matchCondition (likely invalid regex)');
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
isOnCooldown(watcherId, sessionId) {
|
|
326
|
+
const key = `${watcherId}:${sessionId}`;
|
|
327
|
+
const cooldownUntil = this.cooldowns.get(key);
|
|
328
|
+
if (!cooldownUntil) {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
return Date.now() < cooldownUntil;
|
|
332
|
+
}
|
|
333
|
+
setCooldown(watcherId, sessionId, durationMs) {
|
|
334
|
+
const key = `${watcherId}:${sessionId}`;
|
|
335
|
+
this.cooldowns.set(key, Date.now() + durationMs);
|
|
336
|
+
}
|
|
337
|
+
clearCooldown(watcherId, sessionId) {
|
|
338
|
+
const key = `${watcherId}:${sessionId}`;
|
|
339
|
+
this.cooldowns.delete(key);
|
|
340
|
+
}
|
|
341
|
+
computeViewportHash(viewport) {
|
|
342
|
+
return (0, crypto_1.createHash)('sha256').update(viewport).digest('hex').slice(0, 16);
|
|
343
|
+
}
|
|
344
|
+
checkTriggerEligibility(watcher, sessionId, viewport, conditionMatched) {
|
|
345
|
+
const watcherId = watcher.id;
|
|
346
|
+
const viewportHash = this.computeViewportHash(viewport);
|
|
347
|
+
const previousState = this.getLastConditionState(watcherId, sessionId);
|
|
348
|
+
this.setLastConditionState(watcherId, sessionId, conditionMatched);
|
|
349
|
+
if (conditionMatched) {
|
|
350
|
+
if (watcher.cooldownMode === 'time') {
|
|
351
|
+
if (this.isOnCooldown(watcherId, sessionId)) {
|
|
352
|
+
this.logger.debug({ watcherId, sessionId }, 'Skipping trigger: time-based cooldown active');
|
|
353
|
+
return { shouldTrigger: false, viewportHash };
|
|
354
|
+
}
|
|
355
|
+
if (watcher.cooldownMs === 0) {
|
|
356
|
+
const lastHash = this.getLastTriggeredHash(watcherId, sessionId);
|
|
357
|
+
if (lastHash === viewportHash) {
|
|
358
|
+
this.logger.debug({ watcherId, sessionId, viewportHash }, 'Skipping trigger: viewport unchanged (hash dedup)');
|
|
359
|
+
return { shouldTrigger: false, viewportHash };
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
else if (watcher.cooldownMode === 'until_clear') {
|
|
364
|
+
if (previousState === true) {
|
|
365
|
+
this.logger.debug({ watcherId, sessionId }, 'Skipping trigger: until_clear mode, condition already true');
|
|
366
|
+
return { shouldTrigger: false, viewportHash };
|
|
367
|
+
}
|
|
368
|
+
if (this.cooldowns.has(`${watcherId}:${sessionId}`)) {
|
|
369
|
+
this.logger.debug({ watcherId, sessionId }, 'Skipping trigger: until_clear mode, cooldown not cleared');
|
|
370
|
+
return { shouldTrigger: false, viewportHash };
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
this.setCooldown(watcherId, sessionId, watcher.cooldownMs);
|
|
374
|
+
this.setLastTriggeredHash(watcherId, sessionId, viewportHash);
|
|
375
|
+
this.logger.debug({ watcherId, sessionId, viewportHash, cooldownMode: watcher.cooldownMode }, 'Trigger approved');
|
|
376
|
+
return { shouldTrigger: true, viewportHash };
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
if (watcher.cooldownMode === 'until_clear') {
|
|
380
|
+
this.clearCooldown(watcherId, sessionId);
|
|
381
|
+
this.logger.debug({ watcherId, sessionId }, 'Cleared cooldown: condition no longer matches (until_clear mode)');
|
|
382
|
+
}
|
|
383
|
+
return { shouldTrigger: false, viewportHash };
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
getLastConditionState(watcherId, sessionId) {
|
|
387
|
+
const key = `${watcherId}:${sessionId}`;
|
|
388
|
+
return this.lastConditionState.get(key);
|
|
389
|
+
}
|
|
390
|
+
setLastConditionState(watcherId, sessionId, matched) {
|
|
391
|
+
const key = `${watcherId}:${sessionId}`;
|
|
392
|
+
this.lastConditionState.set(key, matched);
|
|
393
|
+
}
|
|
394
|
+
getLastTriggeredHash(watcherId, sessionId) {
|
|
395
|
+
const key = `${watcherId}:${sessionId}`;
|
|
396
|
+
return this.lastTriggeredHash.get(key);
|
|
397
|
+
}
|
|
398
|
+
setLastTriggeredHash(watcherId, sessionId, hash) {
|
|
399
|
+
const key = `${watcherId}:${sessionId}`;
|
|
400
|
+
this.lastTriggeredHash.set(key, hash);
|
|
401
|
+
}
|
|
402
|
+
incrementTriggerCount(watcherId, sessionId) {
|
|
403
|
+
const key = `${watcherId}:${sessionId}`;
|
|
404
|
+
const current = this.triggerCounts.get(key) ?? 0;
|
|
405
|
+
const next = current + 1;
|
|
406
|
+
this.triggerCounts.set(key, next);
|
|
407
|
+
return next;
|
|
408
|
+
}
|
|
409
|
+
getTriggerCount(watcherId, sessionId) {
|
|
410
|
+
const key = `${watcherId}:${sessionId}`;
|
|
411
|
+
return this.triggerCounts.get(key) ?? 0;
|
|
412
|
+
}
|
|
413
|
+
isWatcherRunning(watcherId) {
|
|
414
|
+
return this.pollIntervals.has(watcherId);
|
|
415
|
+
}
|
|
416
|
+
getRunningWatcherIds() {
|
|
417
|
+
return [...this.pollIntervals.keys()];
|
|
418
|
+
}
|
|
419
|
+
async testWatcher(watcher) {
|
|
420
|
+
this.logger.debug({ watcherId: watcher.id, name: watcher.name }, 'Testing watcher');
|
|
421
|
+
const sessions = await this.getMatchingSessions(watcher);
|
|
422
|
+
const results = [];
|
|
423
|
+
for (const session of sessions) {
|
|
424
|
+
if (!session.tmuxSessionId) {
|
|
425
|
+
results.push({
|
|
426
|
+
sessionId: session.id,
|
|
427
|
+
agentId: session.agentId ?? null,
|
|
428
|
+
tmuxSessionId: null,
|
|
429
|
+
viewport: null,
|
|
430
|
+
viewportHash: null,
|
|
431
|
+
conditionMatched: false,
|
|
432
|
+
});
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
try {
|
|
436
|
+
const viewport = await this.captureViewport(session.tmuxSessionId, watcher.viewportLines);
|
|
437
|
+
const viewportHash = viewport ? this.computeViewportHash(viewport) : null;
|
|
438
|
+
const conditionMatched = viewport
|
|
439
|
+
? this.matchCondition(watcher.condition, viewport)
|
|
440
|
+
: false;
|
|
441
|
+
results.push({
|
|
442
|
+
sessionId: session.id,
|
|
443
|
+
agentId: session.agentId ?? null,
|
|
444
|
+
tmuxSessionId: session.tmuxSessionId,
|
|
445
|
+
viewport: viewport || null,
|
|
446
|
+
viewportHash,
|
|
447
|
+
conditionMatched,
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
catch (error) {
|
|
451
|
+
this.logger.warn({ watcherId: watcher.id, sessionId: session.id, error: String(error) }, 'Error testing session');
|
|
452
|
+
results.push({
|
|
453
|
+
sessionId: session.id,
|
|
454
|
+
agentId: session.agentId ?? null,
|
|
455
|
+
tmuxSessionId: session.tmuxSessionId,
|
|
456
|
+
viewport: null,
|
|
457
|
+
viewportHash: null,
|
|
458
|
+
conditionMatched: false,
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
this.logger.debug({ watcherId: watcher.id, sessionsChecked: results.length }, 'Watcher test completed');
|
|
463
|
+
return results;
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
exports.WatcherRunnerService = WatcherRunnerService;
|
|
467
|
+
exports.WatcherRunnerService = WatcherRunnerService = __decorate([
|
|
468
|
+
(0, common_1.Injectable)(),
|
|
469
|
+
__param(0, (0, common_1.Inject)(storage_interface_1.STORAGE_SERVICE)),
|
|
470
|
+
__param(1, (0, common_1.Inject)((0, common_1.forwardRef)(() => sessions_service_1.SessionsService))),
|
|
471
|
+
__param(2, (0, common_1.Inject)((0, common_1.forwardRef)(() => tmux_service_1.TmuxService))),
|
|
472
|
+
__param(3, (0, common_1.Inject)((0, common_1.forwardRef)(() => events_service_1.EventsService))),
|
|
473
|
+
__metadata("design:paramtypes", [Object, sessions_service_1.SessionsService,
|
|
474
|
+
tmux_service_1.TmuxService,
|
|
475
|
+
events_service_1.EventsService])
|
|
476
|
+
], WatcherRunnerService);
|
|
477
|
+
//# sourceMappingURL=watcher-runner.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher-runner.service.js","sourceRoot":"","sources":["../../../../src/modules/watchers/services/watcher-runner.service.ts"],"names":[],"mappings":"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"}
|