@adriandmitroca/relay 0.0.2
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 +121 -0
- package/dist/assets/index-BcE2ldjQ.css +1 -0
- package/dist/assets/index-RaJgQa_m.js +15 -0
- package/dist/index.html +16 -0
- package/package.json +47 -0
- package/scripts/install-service.sh +52 -0
- package/scripts/uninstall-service.sh +10 -0
- package/src/api/config.ts +481 -0
- package/src/api/issues.ts +81 -0
- package/src/api/middleware.ts +14 -0
- package/src/api/router.ts +31 -0
- package/src/cli.ts +184 -0
- package/src/config.ts +195 -0
- package/src/constants.ts +21 -0
- package/src/daemon.ts +1096 -0
- package/src/dashboard.ts +175 -0
- package/src/db.ts +718 -0
- package/src/notifications/telegram.ts +334 -0
- package/src/queue.ts +98 -0
- package/src/sources/asana.ts +161 -0
- package/src/sources/jira.ts +255 -0
- package/src/sources/linear.ts +233 -0
- package/src/sources/sentry.ts +222 -0
- package/src/sources/types.ts +20 -0
- package/src/utils/html.ts +23 -0
- package/src/utils/logger.ts +49 -0
- package/src/worker/claude.ts +297 -0
- package/src/worker/fix.ts +195 -0
- package/src/worker/git.ts +111 -0
- package/src/worker/triage.ts +122 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { runClaudeJson, type ClaudeOptions, type ClaudeStreamEvent } from "./claude.ts";
|
|
2
|
+
import { logger } from "../utils/logger.ts";
|
|
3
|
+
|
|
4
|
+
export interface TriageResult {
|
|
5
|
+
fixable: boolean;
|
|
6
|
+
confidence: number;
|
|
7
|
+
reason: string;
|
|
8
|
+
plan: string | null;
|
|
9
|
+
failed?: boolean;
|
|
10
|
+
failureReason?: string;
|
|
11
|
+
sessionId?: string;
|
|
12
|
+
durationMs: number;
|
|
13
|
+
inputTokens: number;
|
|
14
|
+
outputTokens: number;
|
|
15
|
+
costUsd?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function triageIssue(
|
|
19
|
+
issueContext: string,
|
|
20
|
+
repoPath: string,
|
|
21
|
+
timeoutMs: number,
|
|
22
|
+
projectContext?: string,
|
|
23
|
+
model?: "sonnet" | "opus" | "haiku",
|
|
24
|
+
onEvent?: (event: ClaudeStreamEvent) => void,
|
|
25
|
+
logPath?: string,
|
|
26
|
+
): Promise<TriageResult> {
|
|
27
|
+
const contextSection = projectContext ? `\nProject conventions and context:\n${projectContext}\n` : "";
|
|
28
|
+
|
|
29
|
+
const prompt = `You are triaging a task to decide if it can be automatically implemented by an AI coding agent.
|
|
30
|
+
|
|
31
|
+
Tasks can be anything: bug fixes, new features, refactors, improvements, chores, etc. Your job is to assess whether this task is well-defined enough and scoped appropriately for an AI agent to implement autonomously.
|
|
32
|
+
${contextSection}
|
|
33
|
+
Analyze this task in the context of the codebase:
|
|
34
|
+
|
|
35
|
+
${issueContext}
|
|
36
|
+
|
|
37
|
+
Steps:
|
|
38
|
+
1. Understand what the task is asking for (bug fix, feature, refactor, etc.)
|
|
39
|
+
2. For bugs: use the stacktrace (if available) to find the exact file(s) and line(s) where the error originates
|
|
40
|
+
3. For features/improvements: identify the relevant files and understand the existing patterns
|
|
41
|
+
4. Read the relevant code to understand what needs to change
|
|
42
|
+
5. Check if tests exist for the affected area
|
|
43
|
+
6. Decide if this is implementable and plan the implementation
|
|
44
|
+
|
|
45
|
+
Respond with ONLY a JSON object:
|
|
46
|
+
{
|
|
47
|
+
"fixable": true/false,
|
|
48
|
+
"confidence": 0.0-1.0,
|
|
49
|
+
"reason": "Brief explanation of what needs to be done and why this is/isn't implementable",
|
|
50
|
+
"plan": "If fixable: numbered steps, each specifying the exact file path, function/line, and what change to make. Include test file if one needs to be added or updated. Be concrete — e.g. 'In src/auth/login.ts line 42, add null check before accessing user.profile'. Otherwise null."
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
IS implementable (common patterns):
|
|
54
|
+
- Bug fixes: null checks, error handling, type errors, off-by-one, wrong comparisons
|
|
55
|
+
- Runtime errors from Sentry — if the stacktrace points to code in this repo, it's likely fixable
|
|
56
|
+
- New features with clear requirements that follow existing patterns in the codebase
|
|
57
|
+
- Refactors with well-defined scope (rename, extract, move, simplify)
|
|
58
|
+
- Adding/updating tests for existing functionality
|
|
59
|
+
- UI changes with clear descriptions (add button, change layout, update text)
|
|
60
|
+
- Adding validation, logging, or error handling
|
|
61
|
+
- Performance improvements with obvious targets
|
|
62
|
+
|
|
63
|
+
NOT implementable:
|
|
64
|
+
- The stacktrace points entirely to third-party code with no app code involved
|
|
65
|
+
- Requires infrastructure, deployment, or config changes outside the repo
|
|
66
|
+
- Needs product/design decisions or clarification from humans — the task description is too vague
|
|
67
|
+
- Would be a large architectural refactor touching many unrelated systems
|
|
68
|
+
- Requires access to external services, APIs, or credentials not in the repo
|
|
69
|
+
|
|
70
|
+
Important: An error that "shouldn't land on Sentry" IS fixable — the fix is to add proper error handling so it doesn't propagate. Missing error handling is a code bug.`;
|
|
71
|
+
|
|
72
|
+
const opts: ClaudeOptions = {
|
|
73
|
+
cwd: repoPath,
|
|
74
|
+
timeoutMs,
|
|
75
|
+
allowedTools: ["Read", "Grep", "Glob"],
|
|
76
|
+
model,
|
|
77
|
+
onEvent,
|
|
78
|
+
logPath,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const result = await runClaudeJson<TriageResult>(prompt, opts);
|
|
82
|
+
|
|
83
|
+
if (!result.success || !result.data) {
|
|
84
|
+
logger.warn("Triage failed", { error: result.error });
|
|
85
|
+
const failureReason = result.error?.includes("Timed out") ? "triage:timeout" : "triage:claude_failed";
|
|
86
|
+
return {
|
|
87
|
+
fixable: false,
|
|
88
|
+
confidence: 0,
|
|
89
|
+
reason: `Triage failed: ${result.error ?? "unknown error"}`,
|
|
90
|
+
plan: null,
|
|
91
|
+
failed: true,
|
|
92
|
+
failureReason,
|
|
93
|
+
durationMs: result.durationMs,
|
|
94
|
+
inputTokens: result.inputTokens,
|
|
95
|
+
outputTokens: result.outputTokens,
|
|
96
|
+
costUsd: result.costUsd,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const data = result.data;
|
|
101
|
+
logger.info("Triage complete", {
|
|
102
|
+
fixable: data.fixable,
|
|
103
|
+
confidence: data.confidence,
|
|
104
|
+
reason: data.reason,
|
|
105
|
+
sessionId: result.sessionId,
|
|
106
|
+
durationMs: result.durationMs,
|
|
107
|
+
inputTokens: result.inputTokens,
|
|
108
|
+
outputTokens: result.outputTokens,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
fixable: !!data.fixable,
|
|
113
|
+
confidence: typeof data.confidence === "number" ? data.confidence : 0,
|
|
114
|
+
reason: data.reason ?? "No reason given",
|
|
115
|
+
plan: data.plan ?? null,
|
|
116
|
+
sessionId: result.sessionId,
|
|
117
|
+
durationMs: result.durationMs,
|
|
118
|
+
inputTokens: result.inputTokens,
|
|
119
|
+
outputTokens: result.outputTokens,
|
|
120
|
+
costUsd: result.costUsd,
|
|
121
|
+
};
|
|
122
|
+
}
|