@phuetz/code-buddy 0.1.24 → 0.1.26
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 +1049 -741
- package/dist/agent/codebuddy-agent.d.ts +5 -0
- package/dist/agent/codebuddy-agent.js +46 -1
- package/dist/agent/codebuddy-agent.js.map +1 -1
- package/dist/agent/execution/agent-executor.d.ts +12 -0
- package/dist/agent/execution/agent-executor.js +147 -6
- package/dist/agent/execution/agent-executor.js.map +1 -1
- package/dist/agent/lessons-tracker.d.ts +50 -0
- package/dist/agent/lessons-tracker.js +234 -0
- package/dist/agent/lessons-tracker.js.map +1 -0
- package/dist/agent/message-queue.d.ts +39 -2
- package/dist/agent/message-queue.js +67 -2
- package/dist/agent/message-queue.js.map +1 -1
- package/dist/agent/middleware/index.d.ts +1 -0
- package/dist/agent/middleware/index.js +1 -0
- package/dist/agent/middleware/index.js.map +1 -1
- package/dist/agent/middleware/workflow-guard.d.ts +21 -0
- package/dist/agent/middleware/workflow-guard.js +94 -0
- package/dist/agent/middleware/workflow-guard.js.map +1 -0
- package/dist/agent/repo-profiler.d.ts +61 -0
- package/dist/agent/repo-profiler.js +295 -0
- package/dist/agent/repo-profiler.js.map +1 -0
- package/dist/agent/response-constraint.d.ts +61 -0
- package/dist/agent/response-constraint.js +91 -0
- package/dist/agent/response-constraint.js.map +1 -0
- package/dist/agent/todo-tracker.d.ts +67 -0
- package/dist/agent/todo-tracker.js +245 -0
- package/dist/agent/todo-tracker.js.map +1 -0
- package/dist/agent/tool-handler.d.ts +11 -0
- package/dist/agent/tool-handler.js +79 -1
- package/dist/agent/tool-handler.js.map +1 -1
- package/dist/agent/types.d.ts +20 -2
- package/dist/agent/wide-research.d.ts +93 -0
- package/dist/agent/wide-research.js +232 -0
- package/dist/agent/wide-research.js.map +1 -0
- package/dist/channels/index.d.ts +2 -0
- package/dist/channels/index.js +2 -0
- package/dist/channels/index.js.map +1 -1
- package/dist/channels/pro/callback-router.d.ts +54 -0
- package/dist/channels/pro/callback-router.js +178 -0
- package/dist/channels/pro/callback-router.js.map +1 -0
- package/dist/channels/pro/ci-watcher.d.ts +86 -0
- package/dist/channels/pro/ci-watcher.js +343 -0
- package/dist/channels/pro/ci-watcher.js.map +1 -0
- package/dist/channels/pro/diff-first.d.ts +63 -0
- package/dist/channels/pro/diff-first.js +187 -0
- package/dist/channels/pro/diff-first.js.map +1 -0
- package/dist/channels/pro/enhanced-commands.d.ts +83 -0
- package/dist/channels/pro/enhanced-commands.js +218 -0
- package/dist/channels/pro/enhanced-commands.js.map +1 -0
- package/dist/channels/pro/index.d.ts +19 -0
- package/dist/channels/pro/index.js +21 -0
- package/dist/channels/pro/index.js.map +1 -0
- package/dist/channels/pro/pro-features.d.ts +79 -0
- package/dist/channels/pro/pro-features.js +203 -0
- package/dist/channels/pro/pro-features.js.map +1 -0
- package/dist/channels/pro/run-commands.d.ts +59 -0
- package/dist/channels/pro/run-commands.js +122 -0
- package/dist/channels/pro/run-commands.js.map +1 -0
- package/dist/channels/pro/run-tracker.d.ts +74 -0
- package/dist/channels/pro/run-tracker.js +252 -0
- package/dist/channels/pro/run-tracker.js.map +1 -0
- package/dist/channels/pro/scoped-auth.d.ts +97 -0
- package/dist/channels/pro/scoped-auth.js +340 -0
- package/dist/channels/pro/scoped-auth.js.map +1 -0
- package/dist/channels/pro/text-formatter.d.ts +27 -0
- package/dist/channels/pro/text-formatter.js +269 -0
- package/dist/channels/pro/text-formatter.js.map +1 -0
- package/dist/channels/pro/types.d.ts +242 -0
- package/dist/channels/pro/types.js +14 -0
- package/dist/channels/pro/types.js.map +1 -0
- package/dist/channels/streaming-policy.d.ts +66 -0
- package/dist/channels/streaming-policy.js +266 -0
- package/dist/channels/streaming-policy.js.map +1 -0
- package/dist/channels/telegram/ci-watcher.d.ts +5 -0
- package/dist/channels/telegram/ci-watcher.js +5 -0
- package/dist/channels/telegram/ci-watcher.js.map +1 -0
- package/dist/channels/telegram/client.d.ts +28 -0
- package/dist/channels/telegram/client.js +147 -1
- package/dist/channels/telegram/client.js.map +1 -1
- package/dist/channels/telegram/diff-first.d.ts +5 -0
- package/dist/channels/telegram/diff-first.js +5 -0
- package/dist/channels/telegram/diff-first.js.map +1 -0
- package/dist/channels/telegram/enhanced-commands.d.ts +6 -0
- package/dist/channels/telegram/enhanced-commands.js +6 -0
- package/dist/channels/telegram/enhanced-commands.js.map +1 -0
- package/dist/channels/telegram/index.d.ts +6 -0
- package/dist/channels/telegram/index.js +6 -0
- package/dist/channels/telegram/index.js.map +1 -1
- package/dist/channels/telegram/pro-formatter.d.ts +30 -0
- package/dist/channels/telegram/pro-formatter.js +276 -0
- package/dist/channels/telegram/pro-formatter.js.map +1 -0
- package/dist/channels/telegram/run-commands.d.ts +5 -0
- package/dist/channels/telegram/run-commands.js +6 -0
- package/dist/channels/telegram/run-commands.js.map +1 -0
- package/dist/channels/telegram/run-tracker.d.ts +5 -0
- package/dist/channels/telegram/run-tracker.js +5 -0
- package/dist/channels/telegram/run-tracker.js.map +1 -0
- package/dist/channels/telegram/scoped-auth.d.ts +6 -0
- package/dist/channels/telegram/scoped-auth.js +5 -0
- package/dist/channels/telegram/scoped-auth.js.map +1 -0
- package/dist/channels/telegram/types.d.ts +34 -0
- package/dist/codebuddy/client.js +14 -1
- package/dist/codebuddy/client.js.map +1 -1
- package/dist/commands/dev/index.d.ts +12 -0
- package/dist/commands/dev/index.js +231 -0
- package/dist/commands/dev/index.js.map +1 -0
- package/dist/commands/dev/workflows.d.ts +31 -0
- package/dist/commands/dev/workflows.js +214 -0
- package/dist/commands/dev/workflows.js.map +1 -0
- package/dist/commands/execpolicy.d.ts +17 -0
- package/dist/commands/execpolicy.js +155 -0
- package/dist/commands/execpolicy.js.map +1 -0
- package/dist/commands/knowledge.d.ts +13 -0
- package/dist/commands/knowledge.js +142 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/lessons.d.ts +11 -0
- package/dist/commands/lessons.js +129 -0
- package/dist/commands/lessons.js.map +1 -0
- package/dist/commands/pairing.d.ts +14 -0
- package/dist/commands/pairing.js +132 -0
- package/dist/commands/pairing.js.map +1 -0
- package/dist/commands/research/index.d.ts +13 -0
- package/dist/commands/research/index.js +91 -0
- package/dist/commands/research/index.js.map +1 -0
- package/dist/commands/run-cli/index.d.ts +11 -0
- package/dist/commands/run-cli/index.js +49 -0
- package/dist/commands/run-cli/index.js.map +1 -0
- package/dist/commands/todos.d.ts +9 -0
- package/dist/commands/todos.js +119 -0
- package/dist/commands/todos.js.map +1 -0
- package/dist/config/toml-config.d.ts +21 -0
- package/dist/config/toml-config.js +15 -0
- package/dist/config/toml-config.js.map +1 -1
- package/dist/context/enhanced-compression.js +12 -1
- package/dist/context/enhanced-compression.js.map +1 -1
- package/dist/context/observation-variator.d.ts +44 -0
- package/dist/context/observation-variator.js +83 -0
- package/dist/context/observation-variator.js.map +1 -0
- package/dist/context/precompaction-flush.d.ts +40 -0
- package/dist/context/precompaction-flush.js +134 -0
- package/dist/context/precompaction-flush.js.map +1 -0
- package/dist/context/restorable-compression.d.ts +80 -0
- package/dist/context/restorable-compression.js +228 -0
- package/dist/context/restorable-compression.js.map +1 -0
- package/dist/daemon/daily-reset.d.ts +77 -0
- package/dist/daemon/daily-reset.js +175 -0
- package/dist/daemon/daily-reset.js.map +1 -0
- package/dist/daemon/index.d.ts +1 -0
- package/dist/daemon/index.js +1 -0
- package/dist/daemon/index.js.map +1 -1
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -1
- package/dist/knowledge/knowledge-manager.d.ts +77 -0
- package/dist/knowledge/knowledge-manager.js +244 -0
- package/dist/knowledge/knowledge-manager.js.map +1 -0
- package/dist/observability/run-store.d.ts +133 -0
- package/dist/observability/run-store.js +419 -0
- package/dist/observability/run-store.js.map +1 -0
- package/dist/observability/run-viewer.d.ts +33 -0
- package/dist/observability/run-viewer.js +254 -0
- package/dist/observability/run-viewer.js.map +1 -0
- package/dist/optimization/cache-breakpoints.d.ts +52 -0
- package/dist/optimization/cache-breakpoints.js +97 -0
- package/dist/optimization/cache-breakpoints.js.map +1 -0
- package/dist/persistence/session-store.d.ts +3 -1
- package/dist/persistence/session-store.js +1 -1
- package/dist/persistence/session-store.js.map +1 -1
- package/dist/prompts/system-base.js +51 -7
- package/dist/prompts/system-base.js.map +1 -1
- package/dist/prompts/variation-injector.d.ts +55 -0
- package/dist/prompts/variation-injector.js +171 -0
- package/dist/prompts/variation-injector.js.map +1 -0
- package/dist/prompts/workflow-rules.d.ts +10 -0
- package/dist/prompts/workflow-rules.js +79 -0
- package/dist/prompts/workflow-rules.js.map +1 -0
- package/dist/sandbox/execpolicy.d.ts +45 -0
- package/dist/sandbox/execpolicy.js +80 -0
- package/dist/sandbox/execpolicy.js.map +1 -1
- package/dist/sandbox/os-sandbox.d.ts +25 -0
- package/dist/sandbox/os-sandbox.js +73 -0
- package/dist/sandbox/os-sandbox.js.map +1 -1
- package/dist/security/security-audit.d.ts +10 -0
- package/dist/security/security-audit.js +116 -0
- package/dist/security/security-audit.js.map +1 -1
- package/dist/security/shell-env-policy.d.ts +45 -0
- package/dist/security/shell-env-policy.js +141 -0
- package/dist/security/shell-env-policy.js.map +1 -0
- package/dist/security/ssrf-guard.d.ts +61 -0
- package/dist/security/ssrf-guard.js +382 -0
- package/dist/security/ssrf-guard.js.map +1 -0
- package/dist/security/write-policy.d.ts +57 -0
- package/dist/security/write-policy.js +117 -0
- package/dist/security/write-policy.js.map +1 -0
- package/dist/services/prompt-builder.js +37 -0
- package/dist/services/prompt-builder.js.map +1 -1
- package/dist/themes/theme-schema.d.ts +10 -10
- package/dist/tools/ask-human-tool.d.ts +62 -0
- package/dist/tools/ask-human-tool.js +112 -0
- package/dist/tools/ask-human-tool.js.map +1 -0
- package/dist/tools/bash/bash-tool.d.ts +15 -0
- package/dist/tools/bash/bash-tool.js +62 -0
- package/dist/tools/bash/bash-tool.js.map +1 -1
- package/dist/tools/bash/command-validator.d.ts +1 -0
- package/dist/tools/bash/command-validator.js +5 -0
- package/dist/tools/bash/command-validator.js.map +1 -1
- package/dist/tools/create-skill-tool.d.ts +87 -0
- package/dist/tools/create-skill-tool.js +142 -0
- package/dist/tools/create-skill-tool.js.map +1 -0
- package/dist/tools/fetch-tool.js +5 -3
- package/dist/tools/fetch-tool.js.map +1 -1
- package/dist/tools/hooks/default-hooks.js +24 -23
- package/dist/tools/hooks/default-hooks.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +1 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/plan-tool.d.ts +22 -0
- package/dist/tools/plan-tool.js +128 -0
- package/dist/tools/plan-tool.js.map +1 -0
- package/dist/tools/registry/attention-tools.d.ts +32 -0
- package/dist/tools/registry/attention-tools.js +225 -0
- package/dist/tools/registry/attention-tools.js.map +1 -0
- package/dist/tools/registry/index.d.ts +9 -1
- package/dist/tools/registry/index.js +30 -2
- package/dist/tools/registry/index.js.map +1 -1
- package/dist/tools/registry/knowledge-tools.d.ts +46 -0
- package/dist/tools/registry/knowledge-tools.js +293 -0
- package/dist/tools/registry/knowledge-tools.js.map +1 -0
- package/dist/tools/registry/lessons-tools.d.ts +48 -0
- package/dist/tools/registry/lessons-tools.js +359 -0
- package/dist/tools/registry/lessons-tools.js.map +1 -0
- package/dist/tools/registry/plan-tools.d.ts +2 -0
- package/dist/tools/registry/plan-tools.js +7 -0
- package/dist/tools/registry/plan-tools.js.map +1 -0
- package/dist/tools/registry/script-tools.d.ts +2 -0
- package/dist/tools/registry/script-tools.js +7 -0
- package/dist/tools/registry/script-tools.js.map +1 -0
- package/dist/tools/registry/tool-aliases.d.ts +44 -0
- package/dist/tools/registry/tool-aliases.js +130 -0
- package/dist/tools/registry/tool-aliases.js.map +1 -0
- package/dist/tools/run-script-tool.d.ts +13 -0
- package/dist/tools/run-script-tool.js +146 -0
- package/dist/tools/run-script-tool.js.map +1 -0
- package/dist/tools/web-search.d.ts +25 -0
- package/dist/tools/web-search.js +68 -6
- package/dist/tools/web-search.js.map +1 -1
- package/dist/utils/config-validation/schema.d.ts +2 -2
- package/dist/utils/debug-logger.d.ts +1 -1
- package/dist/utils/rtk-compressor.d.ts +13 -10
- package/dist/utils/rtk-compressor.js +83 -34
- package/dist/utils/rtk-compressor.js.map +1 -1
- package/dist/utils/stable-json.d.ts +27 -0
- package/dist/utils/stable-json.js +50 -0
- package/dist/utils/stable-json.js.map +1 -0
- package/dist/webhooks/webhook-manager.d.ts +7 -0
- package/dist/webhooks/webhook-manager.js +29 -0
- package/dist/webhooks/webhook-manager.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CI Watcher
|
|
3
|
+
*
|
|
4
|
+
* Monitors CI pipelines (GitHub Actions, GitLab CI, Jenkins, custom webhooks)
|
|
5
|
+
* and emits structured events. Channel-agnostic - formatting is handled
|
|
6
|
+
* by the ChannelProFormatter.
|
|
7
|
+
*/
|
|
8
|
+
import { EventEmitter } from 'events';
|
|
9
|
+
/** Default config */
|
|
10
|
+
const DEFAULT_CONFIG = {
|
|
11
|
+
enabled: false,
|
|
12
|
+
chatId: '',
|
|
13
|
+
providers: [],
|
|
14
|
+
alertOn: ['build-failure', 'deploy-failure', 'vulnerable-deps'],
|
|
15
|
+
mutedPatterns: [],
|
|
16
|
+
};
|
|
17
|
+
/** Max events to retain */
|
|
18
|
+
const MAX_EVENTS = 200;
|
|
19
|
+
/**
|
|
20
|
+
* Watches CI pipelines and emits alert events.
|
|
21
|
+
*/
|
|
22
|
+
export class CIWatcher extends EventEmitter {
|
|
23
|
+
config;
|
|
24
|
+
events = new Map();
|
|
25
|
+
deduplication = new Set();
|
|
26
|
+
running = false;
|
|
27
|
+
authManager;
|
|
28
|
+
/** Callback to send alerts (chatId, event, optional analysis) */
|
|
29
|
+
onAlert;
|
|
30
|
+
/** Callback to request LLM cause analysis */
|
|
31
|
+
onAnalysisRequest;
|
|
32
|
+
constructor(config, authManager) {
|
|
33
|
+
super();
|
|
34
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
35
|
+
this.authManager = authManager;
|
|
36
|
+
}
|
|
37
|
+
start() {
|
|
38
|
+
if (this.running)
|
|
39
|
+
return;
|
|
40
|
+
this.running = true;
|
|
41
|
+
this.emit('started');
|
|
42
|
+
}
|
|
43
|
+
stop() {
|
|
44
|
+
this.running = false;
|
|
45
|
+
this.emit('stopped');
|
|
46
|
+
}
|
|
47
|
+
isRunning() {
|
|
48
|
+
return this.running;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Process a webhook payload from any CI provider
|
|
52
|
+
*/
|
|
53
|
+
async processWebhookEvent(payload, provider) {
|
|
54
|
+
if (!this.running)
|
|
55
|
+
return null;
|
|
56
|
+
let event = null;
|
|
57
|
+
switch (provider) {
|
|
58
|
+
case 'github-actions':
|
|
59
|
+
event = this.parseGitHubActionsEvent(payload);
|
|
60
|
+
break;
|
|
61
|
+
case 'gitlab-ci':
|
|
62
|
+
event = this.parseGitLabCIEvent(payload);
|
|
63
|
+
break;
|
|
64
|
+
case 'jenkins':
|
|
65
|
+
event = this.parseJenkinsEvent(payload);
|
|
66
|
+
break;
|
|
67
|
+
case 'custom-webhook':
|
|
68
|
+
event = this.parseCustomWebhookEvent(payload);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
if (!event)
|
|
72
|
+
return null;
|
|
73
|
+
if (!this.config.alertOn.includes(event.type))
|
|
74
|
+
return null;
|
|
75
|
+
const dedupKey = `${event.commit || ''}_${event.workflow || ''}_${event.type}`;
|
|
76
|
+
if (this.deduplication.has(dedupKey))
|
|
77
|
+
return null;
|
|
78
|
+
this.deduplication.add(dedupKey);
|
|
79
|
+
if (this.isMuted(event))
|
|
80
|
+
return null;
|
|
81
|
+
this.events.set(event.id, event);
|
|
82
|
+
this.pruneEvents();
|
|
83
|
+
// Get analysis if available
|
|
84
|
+
let analysis;
|
|
85
|
+
if (this.onAnalysisRequest) {
|
|
86
|
+
try {
|
|
87
|
+
analysis = await this.onAnalysisRequest(event);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Skip analysis on error
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Send alert via callback
|
|
94
|
+
if (this.onAlert && this.config.chatId) {
|
|
95
|
+
await this.onAlert(this.config.chatId, event, analysis);
|
|
96
|
+
}
|
|
97
|
+
this.emit('event', event);
|
|
98
|
+
return event;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Parse GitHub Actions webhook event
|
|
102
|
+
*/
|
|
103
|
+
parseGitHubActionsEvent(payload) {
|
|
104
|
+
const workflowRun = payload.workflow_run;
|
|
105
|
+
const checkRun = payload.check_run;
|
|
106
|
+
const action = payload.action;
|
|
107
|
+
if (workflowRun && action === 'completed') {
|
|
108
|
+
const conclusion = workflowRun.conclusion;
|
|
109
|
+
if (conclusion === 'success')
|
|
110
|
+
return null;
|
|
111
|
+
const repo = payload.repository?.full_name || 'unknown';
|
|
112
|
+
const branch = workflowRun.head_branch || 'unknown';
|
|
113
|
+
const commit = workflowRun.head_sha?.slice(0, 7) || '';
|
|
114
|
+
return {
|
|
115
|
+
id: `gh_${Date.now().toString(36)}`,
|
|
116
|
+
type: conclusion === 'failure' ? 'build-failure' : 'flaky-test',
|
|
117
|
+
provider: 'github-actions',
|
|
118
|
+
repo,
|
|
119
|
+
branch,
|
|
120
|
+
title: `${workflowRun.name || 'Workflow'} ${conclusion}`,
|
|
121
|
+
details: `Workflow "${workflowRun.name}" concluded with ${conclusion} on ${branch}`,
|
|
122
|
+
logUrl: workflowRun.html_url,
|
|
123
|
+
severity: conclusion === 'failure' ? 'error' : 'warning',
|
|
124
|
+
commit,
|
|
125
|
+
workflow: workflowRun.name,
|
|
126
|
+
timestamp: Date.now(),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
if (checkRun && action === 'completed') {
|
|
130
|
+
const conclusion = checkRun.conclusion;
|
|
131
|
+
if (conclusion === 'success')
|
|
132
|
+
return null;
|
|
133
|
+
const repo = payload.repository?.full_name || 'unknown';
|
|
134
|
+
const branch = checkRun.check_suite?.head_branch || 'unknown';
|
|
135
|
+
return {
|
|
136
|
+
id: `gh_${Date.now().toString(36)}`,
|
|
137
|
+
type: 'build-failure',
|
|
138
|
+
provider: 'github-actions',
|
|
139
|
+
repo,
|
|
140
|
+
branch,
|
|
141
|
+
title: `Check "${checkRun.name}" ${conclusion}`,
|
|
142
|
+
details: checkRun.output?.summary || `Check run ${conclusion}`,
|
|
143
|
+
logUrl: checkRun.html_url,
|
|
144
|
+
severity: 'error',
|
|
145
|
+
commit: checkRun.check_suite?.head_sha?.slice(0, 7),
|
|
146
|
+
workflow: checkRun.name,
|
|
147
|
+
timestamp: Date.now(),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
if (payload.deployment_status) {
|
|
151
|
+
const depStatus = payload.deployment_status;
|
|
152
|
+
const state = depStatus.state;
|
|
153
|
+
if (state === 'failure' || state === 'error') {
|
|
154
|
+
const repo = payload.repository?.full_name || 'unknown';
|
|
155
|
+
const env = depStatus.environment || 'unknown';
|
|
156
|
+
return {
|
|
157
|
+
id: `gh_dep_${Date.now().toString(36)}`,
|
|
158
|
+
type: 'deploy-failure',
|
|
159
|
+
provider: 'github-actions',
|
|
160
|
+
repo,
|
|
161
|
+
branch: env,
|
|
162
|
+
title: `Deployment to ${env} failed`,
|
|
163
|
+
details: depStatus.description || `Deployment ${state}`,
|
|
164
|
+
logUrl: depStatus.log_url,
|
|
165
|
+
severity: 'critical',
|
|
166
|
+
timestamp: Date.now(),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Parse GitLab CI webhook event
|
|
174
|
+
*/
|
|
175
|
+
parseGitLabCIEvent(payload) {
|
|
176
|
+
const objectKind = payload.object_kind;
|
|
177
|
+
if (objectKind !== 'pipeline' && objectKind !== 'build')
|
|
178
|
+
return null;
|
|
179
|
+
const status = payload.object_attributes?.status;
|
|
180
|
+
if (status !== 'failed')
|
|
181
|
+
return null;
|
|
182
|
+
const project = payload.project;
|
|
183
|
+
const repo = project?.path_with_namespace || 'unknown';
|
|
184
|
+
const branch = payload.object_attributes?.ref || 'unknown';
|
|
185
|
+
return {
|
|
186
|
+
id: `gl_${Date.now().toString(36)}`,
|
|
187
|
+
type: 'build-failure',
|
|
188
|
+
provider: 'gitlab-ci',
|
|
189
|
+
repo,
|
|
190
|
+
branch,
|
|
191
|
+
title: `${objectKind} failed on ${branch}`,
|
|
192
|
+
details: `${objectKind} #${payload.object_attributes?.id} failed`,
|
|
193
|
+
logUrl: payload.object_attributes?.url,
|
|
194
|
+
severity: 'error',
|
|
195
|
+
commit: payload.object_attributes?.sha?.slice(0, 7),
|
|
196
|
+
timestamp: Date.now(),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Parse Jenkins webhook event
|
|
201
|
+
*/
|
|
202
|
+
parseJenkinsEvent(payload) {
|
|
203
|
+
const build = payload.build;
|
|
204
|
+
if (!build)
|
|
205
|
+
return null;
|
|
206
|
+
const status = build.status || build.phase;
|
|
207
|
+
if (!status || status.toLowerCase() === 'success')
|
|
208
|
+
return null;
|
|
209
|
+
return {
|
|
210
|
+
id: `jk_${Date.now().toString(36)}`,
|
|
211
|
+
type: 'build-failure',
|
|
212
|
+
provider: 'jenkins',
|
|
213
|
+
repo: payload.name || 'unknown',
|
|
214
|
+
branch: build.scm?.branch || 'unknown',
|
|
215
|
+
title: `Build #${build.number} ${status}`,
|
|
216
|
+
details: build.log || `Jenkins build ${status}`,
|
|
217
|
+
logUrl: build.full_url || build.url,
|
|
218
|
+
severity: 'error',
|
|
219
|
+
timestamp: Date.now(),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Parse custom webhook event (generic format)
|
|
224
|
+
*/
|
|
225
|
+
parseCustomWebhookEvent(payload) {
|
|
226
|
+
const type = payload.type;
|
|
227
|
+
if (!type)
|
|
228
|
+
return null;
|
|
229
|
+
return {
|
|
230
|
+
id: `cw_${Date.now().toString(36)}`,
|
|
231
|
+
type,
|
|
232
|
+
provider: 'custom-webhook',
|
|
233
|
+
repo: payload.repo || 'unknown',
|
|
234
|
+
branch: payload.branch || 'unknown',
|
|
235
|
+
title: payload.title || 'CI Event',
|
|
236
|
+
details: payload.details || '',
|
|
237
|
+
logUrl: payload.logUrl,
|
|
238
|
+
severity: payload.severity || 'warning',
|
|
239
|
+
commit: payload.commit,
|
|
240
|
+
workflow: payload.workflow,
|
|
241
|
+
timestamp: Date.now(),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Handle "Fix it" action
|
|
246
|
+
*/
|
|
247
|
+
async handleFixIt(eventId, userId, _chatId) {
|
|
248
|
+
const event = this.events.get(eventId);
|
|
249
|
+
if (!event) {
|
|
250
|
+
return { text: 'Event not found.' };
|
|
251
|
+
}
|
|
252
|
+
if (this.authManager) {
|
|
253
|
+
const decision = this.authManager.checkScope(userId, 'write-patch', {
|
|
254
|
+
repo: event.repo,
|
|
255
|
+
});
|
|
256
|
+
if (!decision.allowed) {
|
|
257
|
+
return { text: `Permission denied: ${decision.reason}` };
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
const objective = `Fix CI failure: ${event.title}. Repo: ${event.repo}, Branch: ${event.branch}. Details: ${event.details.slice(0, 200)}`;
|
|
261
|
+
return {
|
|
262
|
+
text: `Launching fix agent for: ${event.title}`,
|
|
263
|
+
objective,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Handle "Mute" action
|
|
268
|
+
*/
|
|
269
|
+
handleMute(eventId) {
|
|
270
|
+
const event = this.events.get(eventId);
|
|
271
|
+
if (!event) {
|
|
272
|
+
return { text: 'Event not found.' };
|
|
273
|
+
}
|
|
274
|
+
const pattern = `${event.workflow || event.type}_${event.repo}`;
|
|
275
|
+
if (!this.config.mutedPatterns.includes(pattern)) {
|
|
276
|
+
this.config.mutedPatterns.push(pattern);
|
|
277
|
+
}
|
|
278
|
+
return { text: `Muted: ${pattern}. Similar events will be suppressed.` };
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Unmute a pattern
|
|
282
|
+
*/
|
|
283
|
+
handleUnmute(pattern) {
|
|
284
|
+
const idx = this.config.mutedPatterns.indexOf(pattern);
|
|
285
|
+
if (idx >= 0) {
|
|
286
|
+
this.config.mutedPatterns.splice(idx, 1);
|
|
287
|
+
return { text: `Unmuted: ${pattern}` };
|
|
288
|
+
}
|
|
289
|
+
return { text: `Pattern not found: ${pattern}` };
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Get event by ID
|
|
293
|
+
*/
|
|
294
|
+
getEvent(id) {
|
|
295
|
+
return this.events.get(id);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* List recent events
|
|
299
|
+
*/
|
|
300
|
+
listEvents(limit = 20) {
|
|
301
|
+
return Array.from(this.events.values())
|
|
302
|
+
.sort((a, b) => b.timestamp - a.timestamp)
|
|
303
|
+
.slice(0, limit);
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Get current config
|
|
307
|
+
*/
|
|
308
|
+
getConfig() {
|
|
309
|
+
return { ...this.config };
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Update config
|
|
313
|
+
*/
|
|
314
|
+
updateConfig(updates) {
|
|
315
|
+
Object.assign(this.config, updates);
|
|
316
|
+
}
|
|
317
|
+
static getSeverityIcon(severity) {
|
|
318
|
+
switch (severity) {
|
|
319
|
+
case 'info': return '[INFO]';
|
|
320
|
+
case 'warning': return '[WARN]';
|
|
321
|
+
case 'error': return '[ERROR]';
|
|
322
|
+
case 'critical': return '[CRIT]';
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
isMuted(event) {
|
|
326
|
+
const pattern = `${event.workflow || event.type}_${event.repo}`;
|
|
327
|
+
return this.config.mutedPatterns.includes(pattern);
|
|
328
|
+
}
|
|
329
|
+
pruneEvents() {
|
|
330
|
+
if (this.events.size <= MAX_EVENTS)
|
|
331
|
+
return;
|
|
332
|
+
const sorted = Array.from(this.events.entries())
|
|
333
|
+
.sort((a, b) => b[1].timestamp - a[1].timestamp);
|
|
334
|
+
const toRemove = sorted.slice(MAX_EVENTS);
|
|
335
|
+
for (const [id] of toRemove) {
|
|
336
|
+
this.events.delete(id);
|
|
337
|
+
}
|
|
338
|
+
if (this.deduplication.size > MAX_EVENTS * 2) {
|
|
339
|
+
this.deduplication.clear();
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=ci-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-watcher.js","sourceRoot":"","sources":["../../../src/channels/pro/ci-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff-First Manager
|
|
3
|
+
*
|
|
4
|
+
* Preview all code changes before applying them.
|
|
5
|
+
* Channel-agnostic - formatting is handled by the ChannelProFormatter.
|
|
6
|
+
*/
|
|
7
|
+
import type { DiffFirstConfig, FileDiffSummary, PendingDiff, ApplyResult } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Manages diff previews for channel interactions.
|
|
10
|
+
*/
|
|
11
|
+
export declare class DiffFirstManager {
|
|
12
|
+
private pending;
|
|
13
|
+
private config;
|
|
14
|
+
/** Callback invoked when a diff is approved for application */
|
|
15
|
+
onApply?: (diff: PendingDiff) => Promise<ApplyResult>;
|
|
16
|
+
/** Callback invoked when a diff is cancelled */
|
|
17
|
+
onCancel?: (diff: PendingDiff) => Promise<void>;
|
|
18
|
+
constructor(config?: Partial<DiffFirstConfig>);
|
|
19
|
+
/**
|
|
20
|
+
* Create a pending diff for user review
|
|
21
|
+
*/
|
|
22
|
+
createPendingDiff(chatId: string, userId: string, turnId: number, diffs: FileDiffSummary[], plan?: string, fullDiff?: string): PendingDiff;
|
|
23
|
+
/**
|
|
24
|
+
* Format the full unified diff for viewing (pure text, no channel-specific formatting)
|
|
25
|
+
*/
|
|
26
|
+
formatFullDiff(pending: PendingDiff): string;
|
|
27
|
+
/**
|
|
28
|
+
* Handle apply action
|
|
29
|
+
*/
|
|
30
|
+
handleApply(diffId: string, userId: string): Promise<ApplyResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Handle cancel action
|
|
33
|
+
*/
|
|
34
|
+
handleCancel(diffId: string, userId: string): Promise<{
|
|
35
|
+
success: boolean;
|
|
36
|
+
error?: string;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Handle view full diff action
|
|
40
|
+
*/
|
|
41
|
+
handleViewFull(diffId: string): string | null;
|
|
42
|
+
/**
|
|
43
|
+
* Get a pending diff by ID
|
|
44
|
+
*/
|
|
45
|
+
getPendingDiff(id: string): PendingDiff | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Check if auto-apply threshold is met
|
|
48
|
+
*/
|
|
49
|
+
shouldAutoApply(diffs: FileDiffSummary[]): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Clean up expired pending diffs
|
|
52
|
+
*/
|
|
53
|
+
cleanupExpired(): number;
|
|
54
|
+
/**
|
|
55
|
+
* Get current config
|
|
56
|
+
*/
|
|
57
|
+
getConfig(): DiffFirstConfig;
|
|
58
|
+
/**
|
|
59
|
+
* Update config
|
|
60
|
+
*/
|
|
61
|
+
updateConfig(updates: Partial<DiffFirstConfig>): void;
|
|
62
|
+
private enforceLimit;
|
|
63
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff-First Manager
|
|
3
|
+
*
|
|
4
|
+
* Preview all code changes before applying them.
|
|
5
|
+
* Channel-agnostic - formatting is handled by the ChannelProFormatter.
|
|
6
|
+
*/
|
|
7
|
+
import { randomBytes } from 'crypto';
|
|
8
|
+
/** Default config */
|
|
9
|
+
const DEFAULT_CONFIG = {
|
|
10
|
+
enabled: true,
|
|
11
|
+
planFirst: false,
|
|
12
|
+
maxDiffLines: 30,
|
|
13
|
+
autoApplyThreshold: 0,
|
|
14
|
+
};
|
|
15
|
+
/** Max pending diffs to keep in memory */
|
|
16
|
+
const MAX_PENDING = 50;
|
|
17
|
+
/** Default expiry: 30 minutes */
|
|
18
|
+
const DEFAULT_EXPIRY_MS = 30 * 60 * 1000;
|
|
19
|
+
/**
|
|
20
|
+
* Manages diff previews for channel interactions.
|
|
21
|
+
*/
|
|
22
|
+
export class DiffFirstManager {
|
|
23
|
+
pending = new Map();
|
|
24
|
+
config;
|
|
25
|
+
/** Callback invoked when a diff is approved for application */
|
|
26
|
+
onApply;
|
|
27
|
+
/** Callback invoked when a diff is cancelled */
|
|
28
|
+
onCancel;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a pending diff for user review
|
|
34
|
+
*/
|
|
35
|
+
createPendingDiff(chatId, userId, turnId, diffs, plan, fullDiff) {
|
|
36
|
+
const id = randomBytes(3).toString('hex');
|
|
37
|
+
const pending = {
|
|
38
|
+
id,
|
|
39
|
+
chatId,
|
|
40
|
+
userId,
|
|
41
|
+
turnId,
|
|
42
|
+
diffs,
|
|
43
|
+
plan,
|
|
44
|
+
fullDiff,
|
|
45
|
+
status: 'pending',
|
|
46
|
+
createdAt: Date.now(),
|
|
47
|
+
expiresAt: Date.now() + DEFAULT_EXPIRY_MS,
|
|
48
|
+
};
|
|
49
|
+
this.pending.set(id, pending);
|
|
50
|
+
this.enforceLimit();
|
|
51
|
+
return pending;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Format the full unified diff for viewing (pure text, no channel-specific formatting)
|
|
55
|
+
*/
|
|
56
|
+
formatFullDiff(pending) {
|
|
57
|
+
if (pending.fullDiff) {
|
|
58
|
+
return pending.fullDiff;
|
|
59
|
+
}
|
|
60
|
+
const lines = [];
|
|
61
|
+
for (const diff of pending.diffs) {
|
|
62
|
+
lines.push(`--- a/${diff.path}`);
|
|
63
|
+
lines.push(`+++ b/${diff.path}`);
|
|
64
|
+
if (diff.excerpt) {
|
|
65
|
+
lines.push(diff.excerpt);
|
|
66
|
+
}
|
|
67
|
+
lines.push('');
|
|
68
|
+
}
|
|
69
|
+
return lines.join('\n');
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Handle apply action
|
|
73
|
+
*/
|
|
74
|
+
async handleApply(diffId, userId) {
|
|
75
|
+
const pending = this.pending.get(diffId);
|
|
76
|
+
if (!pending) {
|
|
77
|
+
return { success: false, filesApplied: 0, error: 'Diff not found or expired' };
|
|
78
|
+
}
|
|
79
|
+
if (pending.userId !== userId) {
|
|
80
|
+
return { success: false, filesApplied: 0, error: 'Only the requesting user can apply' };
|
|
81
|
+
}
|
|
82
|
+
if (pending.status !== 'pending') {
|
|
83
|
+
return { success: false, filesApplied: 0, error: `Diff already ${pending.status}` };
|
|
84
|
+
}
|
|
85
|
+
if (Date.now() > pending.expiresAt) {
|
|
86
|
+
pending.status = 'expired';
|
|
87
|
+
return { success: false, filesApplied: 0, error: 'Diff has expired' };
|
|
88
|
+
}
|
|
89
|
+
if (this.onApply) {
|
|
90
|
+
const result = await this.onApply(pending);
|
|
91
|
+
pending.status = result.success ? 'applied' : 'pending';
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
pending.status = 'applied';
|
|
95
|
+
return { success: true, filesApplied: pending.diffs.length };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Handle cancel action
|
|
99
|
+
*/
|
|
100
|
+
async handleCancel(diffId, userId) {
|
|
101
|
+
const pending = this.pending.get(diffId);
|
|
102
|
+
if (!pending) {
|
|
103
|
+
return { success: false, error: 'Diff not found' };
|
|
104
|
+
}
|
|
105
|
+
if (pending.userId !== userId) {
|
|
106
|
+
return { success: false, error: 'Only the requesting user can cancel' };
|
|
107
|
+
}
|
|
108
|
+
if (pending.status !== 'pending') {
|
|
109
|
+
return { success: false, error: `Diff already ${pending.status}` };
|
|
110
|
+
}
|
|
111
|
+
pending.status = 'cancelled';
|
|
112
|
+
if (this.onCancel) {
|
|
113
|
+
await this.onCancel(pending);
|
|
114
|
+
}
|
|
115
|
+
return { success: true };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Handle view full diff action
|
|
119
|
+
*/
|
|
120
|
+
handleViewFull(diffId) {
|
|
121
|
+
const pending = this.pending.get(diffId);
|
|
122
|
+
if (!pending)
|
|
123
|
+
return null;
|
|
124
|
+
return this.formatFullDiff(pending);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get a pending diff by ID
|
|
128
|
+
*/
|
|
129
|
+
getPendingDiff(id) {
|
|
130
|
+
return this.pending.get(id);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if auto-apply threshold is met
|
|
134
|
+
*/
|
|
135
|
+
shouldAutoApply(diffs) {
|
|
136
|
+
if (this.config.autoApplyThreshold <= 0)
|
|
137
|
+
return false;
|
|
138
|
+
const totalChanges = diffs.reduce((sum, d) => sum + d.linesAdded + d.linesRemoved, 0);
|
|
139
|
+
return totalChanges <= this.config.autoApplyThreshold;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Clean up expired pending diffs
|
|
143
|
+
*/
|
|
144
|
+
cleanupExpired() {
|
|
145
|
+
let cleaned = 0;
|
|
146
|
+
const now = Date.now();
|
|
147
|
+
for (const [id, diff] of this.pending) {
|
|
148
|
+
if (diff.status === 'pending' && now > diff.expiresAt) {
|
|
149
|
+
diff.status = 'expired';
|
|
150
|
+
cleaned++;
|
|
151
|
+
}
|
|
152
|
+
if (diff.status !== 'pending' && now - diff.createdAt > 3600_000) {
|
|
153
|
+
this.pending.delete(id);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return cleaned;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get current config
|
|
160
|
+
*/
|
|
161
|
+
getConfig() {
|
|
162
|
+
return { ...this.config };
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Update config
|
|
166
|
+
*/
|
|
167
|
+
updateConfig(updates) {
|
|
168
|
+
Object.assign(this.config, updates);
|
|
169
|
+
}
|
|
170
|
+
enforceLimit() {
|
|
171
|
+
if (this.pending.size <= MAX_PENDING)
|
|
172
|
+
return;
|
|
173
|
+
const entries = Array.from(this.pending.entries())
|
|
174
|
+
.sort((a, b) => a[1].createdAt - b[1].createdAt);
|
|
175
|
+
while (this.pending.size > MAX_PENDING && entries.length > 0) {
|
|
176
|
+
const [id, diff] = entries.shift();
|
|
177
|
+
if (diff.status !== 'pending') {
|
|
178
|
+
this.pending.delete(id);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
while (this.pending.size > MAX_PENDING && entries.length > 0) {
|
|
182
|
+
const [id] = entries.shift();
|
|
183
|
+
this.pending.delete(id);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=diff-first.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-first.js","sourceRoot":"","sources":["../../../src/channels/pro/diff-first.ts"],"names":[],"mappings":"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"}
|