ework-web 0.10.68 → 0.10.70
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/package.json +1 -1
- package/src/index.ts +16 -0
- package/src/webhooks.ts +30 -2
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1339,6 +1339,22 @@ async function handle(req: Request, url: URL, ip: string, ctx: { authed: boolean
|
|
|
1339
1339
|
}
|
|
1340
1340
|
}
|
|
1341
1341
|
|
|
1342
|
+
if (url.pathname === "/api/v1/dispatch-state" && req.method === "GET") {
|
|
1343
|
+
const owner = url.searchParams.get("owner") ?? "";
|
|
1344
|
+
const repo = url.searchParams.get("repo") ?? "";
|
|
1345
|
+
const number = url.searchParams.get("number") ?? "";
|
|
1346
|
+
if (!owner || !repo || !number) return json({ error: "owner, repo, number required" }, 400);
|
|
1347
|
+
const project = await getProject(owner, repo);
|
|
1348
|
+
if (!project) return json({ dispatchOff: false, aiStatus: "" });
|
|
1349
|
+
const issue = await getIssueWithMeta(project.id, Number(number));
|
|
1350
|
+
const cfgKv = await getConfigAll();
|
|
1351
|
+
const globalOff = cfgKv["dispatchEnabled"] === "false";
|
|
1352
|
+
const projectOff = cfgKv[`dispatchOff:${owner}/${repo}`] === "1";
|
|
1353
|
+
const aiStatus = issue?.ai_status ?? "";
|
|
1354
|
+
const issueOff = aiStatus === "dispatch_off" || aiStatus === "halted";
|
|
1355
|
+
return json({ dispatchOff: globalOff || projectOff || issueOff, aiStatus });
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1342
1358
|
if (url.pathname === "/api/router/strategy") {
|
|
1343
1359
|
if (!ctx.user || ctx.user.is_admin !== 1) return json({ error: "admin required" }, 403);
|
|
1344
1360
|
const routerUrl = cfg.daemonWebhookUrl.replace(/\/$/, "");
|
package/src/webhooks.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
resolveModel,
|
|
29
29
|
listLabelsForIssue,
|
|
30
30
|
getUserByLogin,
|
|
31
|
+
type UserRow,
|
|
31
32
|
type IssueRow,
|
|
32
33
|
type ProjectRow,
|
|
33
34
|
type CommentRow,
|
|
@@ -229,6 +230,9 @@ interface PayloadUser {
|
|
|
229
230
|
html_url: string;
|
|
230
231
|
is_admin: boolean;
|
|
231
232
|
language: string;
|
|
233
|
+
kind?: string;
|
|
234
|
+
display_name?: string | null;
|
|
235
|
+
is_active?: boolean;
|
|
232
236
|
}
|
|
233
237
|
|
|
234
238
|
interface PayloadLabel {
|
|
@@ -348,6 +352,18 @@ function buildUser(login: string, origin: string): PayloadUser {
|
|
|
348
352
|
};
|
|
349
353
|
}
|
|
350
354
|
|
|
355
|
+
function buildUserFromRow(user: UserRow, origin: string): PayloadUser {
|
|
356
|
+
return {
|
|
357
|
+
...buildUser(user.login, origin),
|
|
358
|
+
full_name: user.display_name ?? user.login,
|
|
359
|
+
email: user.email ?? `${user.login}@${new URL(origin).host ?? "localhost"}.noreply.ework`,
|
|
360
|
+
is_admin: user.is_admin === 1,
|
|
361
|
+
kind: user.kind,
|
|
362
|
+
display_name: user.display_name,
|
|
363
|
+
is_active: user.is_active === 1,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
351
367
|
function buildRepository(project: ProjectRow, origin: string, model?: string): PayloadRepository {
|
|
352
368
|
const fullName = `${project.owner}/${project.name}`;
|
|
353
369
|
const htmlUrl = `${origin}/${encodeURIComponent(project.owner)}/${encodeURIComponent(project.name)}`;
|
|
@@ -656,6 +672,11 @@ export async function emitIssueEvent(
|
|
|
656
672
|
const payload = buildIssuePayload(issue, project, commentCount, action, origin, model, labels);
|
|
657
673
|
(payload as IssueEventPayload).event_id = randomUUID();
|
|
658
674
|
(payload as IssueEventPayload).dispatch_off = dispatchOff;
|
|
675
|
+
const authorUser = await getUserByLogin(issue.author);
|
|
676
|
+
if (authorUser) {
|
|
677
|
+
payload.sender = buildUserFromRow(authorUser, origin);
|
|
678
|
+
payload.issue.user = buildUserFromRow(authorUser, origin);
|
|
679
|
+
}
|
|
659
680
|
const rawBody = JSON.stringify(payload);
|
|
660
681
|
await fanOut(projectId, "issues", rawBody);
|
|
661
682
|
} catch (e) {
|
|
@@ -690,7 +711,13 @@ export async function emitCommentEvent(
|
|
|
690
711
|
const labels = await toPayloadLabels(issueId);
|
|
691
712
|
const payload = buildCommentPayload(issue, comment, project, commentCount, origin, model, labels);
|
|
692
713
|
(payload as CommentEventPayload).event_id = randomUUID();
|
|
693
|
-
(
|
|
714
|
+
if (authorUser) {
|
|
715
|
+
payload.sender = buildUserFromRow(authorUser, origin);
|
|
716
|
+
payload.comment.user = buildUserFromRow(authorUser, origin);
|
|
717
|
+
(payload as CommentEventPayload).comment.author_kind = authorUser.kind;
|
|
718
|
+
} else {
|
|
719
|
+
(payload as CommentEventPayload).comment.author_kind = "human";
|
|
720
|
+
}
|
|
694
721
|
const rawBody = JSON.stringify(payload);
|
|
695
722
|
await fanOut(projectId, "issue_comment", rawBody);
|
|
696
723
|
} catch (e) {
|
|
@@ -718,8 +745,9 @@ export async function emitStatusChanged(
|
|
|
718
745
|
const issue = await getIssueById(issueId);
|
|
719
746
|
if (!issue) { log.warn(`emitStatusChanged: issue ${issueId} not found (project=${projectId}) — silent skip prevented`); return; }
|
|
720
747
|
const commentCount = await countCommentsSafe(issueId);
|
|
748
|
+
const actorUser = await getUserByLogin(actor);
|
|
749
|
+
const sender = actorUser ? buildUserFromRow(actorUser, origin) : buildUser(actor, origin);
|
|
721
750
|
const repo = buildRepository(project, origin);
|
|
722
|
-
const sender = buildUser(actor, origin);
|
|
723
751
|
const issuePayload = buildIssue(issue, project, commentCount, origin);
|
|
724
752
|
const payload: StatusChangedPayload = {
|
|
725
753
|
event_id: randomUUID(),
|