ework-web 0.10.114 → 0.10.116

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ework-web",
3
- "version": "0.10.114",
3
+ "version": "0.10.116",
4
4
  "type": "module",
5
5
  "description": "ework-web — standalone multi-project issue tracker. Local SQLite-backed, no external API dependency. Bun + TypeScript + SSR HTML.",
6
6
  "license": "MIT",
package/src/giteaApi.ts CHANGED
@@ -349,6 +349,11 @@ export async function handleGiteaApi(
349
349
  const body = (await readJson(req).catch(() => ({}))) as { model?: unknown };
350
350
  const model = typeof body.model === "string" ? body.model.trim() : "";
351
351
  await updateCommentModel(cid, model);
352
+ const tagged = await getComment(cid);
353
+ if (tagged && model) {
354
+ const taggedIssue = await getIssueById(tagged.issue_id);
355
+ if (taggedIssue) void emitCommentEvent(project.id, taggedIssue.id, cid, origin, "edited");
356
+ }
352
357
  return { status: 200, body: { ok: true, model } };
353
358
  } catch (e) {
354
359
  return giteaError(500, e instanceof Error ? e.message : String(e));
package/src/index.ts CHANGED
@@ -43,6 +43,7 @@ import {
43
43
  updateIssueModel,
44
44
  updateIssueRuntime,
45
45
  listIssues,
46
+ listCommentsForIssue,
46
47
  createAttachment,
47
48
  getAttachment,
48
49
  verifyUserPassword,
@@ -625,6 +626,65 @@ async function handle(req: Request, url: URL, ip: string, ctx: { authed: boolean
625
626
  .split(/[\s,]+/).map((s) => s.trim()).filter(Boolean);
626
627
  return json({ logins });
627
628
  }
629
+
630
+ // Issues JSON API — read side for the ework-issue CLI (pull/open).
631
+ if (url.pathname === "/api/v1/issues" && req.method === "GET") {
632
+ const owner = url.searchParams.get("owner") ?? "";
633
+ const repo = url.searchParams.get("repo") ?? "";
634
+ if (!owner || !repo) return json({ error: "owner, repo required" }, 400);
635
+ const project = await getProject(owner, repo);
636
+ if (!project) return json({ error: "project not found" }, 404);
637
+ const sp = url.searchParams.get("state");
638
+ const state = sp === "open" || sp === "closed" ? sp : "all";
639
+ const rows = await listIssues(project.id, { state, limit: 200 });
640
+ return json({
641
+ project: { owner, name: repo },
642
+ issues: rows.map((i) => ({
643
+ number: i.number,
644
+ title: i.title,
645
+ state: i.state,
646
+ author: i.author,
647
+ ai_status: i.ai_status ?? "",
648
+ model: i.model ?? "",
649
+ comment_count: i.comment_count,
650
+ created_at: i.created_at,
651
+ updated_at: i.updated_at,
652
+ })),
653
+ });
654
+ }
655
+ const apiIssueDetail = url.pathname.match(/^\/api\/v1\/issues\/(\d+)$/);
656
+ if (apiIssueDetail && req.method === "GET") {
657
+ const owner = url.searchParams.get("owner") ?? "";
658
+ const repo = url.searchParams.get("repo") ?? "";
659
+ if (!owner || !repo) return json({ error: "owner, repo required" }, 400);
660
+ const project = await getProject(owner, repo);
661
+ if (!project) return json({ error: "project not found" }, 404);
662
+ const issue = await getIssueWithMeta(project.id, Number(apiIssueDetail[1]));
663
+ if (!issue) return json({ error: "issue not found" }, 404);
664
+ const comments = await listCommentsForIssue(issue.id);
665
+ return json({
666
+ issue: {
667
+ number: issue.number,
668
+ title: issue.title,
669
+ body: issue.body,
670
+ state: issue.state,
671
+ author: issue.author,
672
+ ai_status: issue.ai_status ?? "",
673
+ model: issue.model ?? "",
674
+ created_at: issue.created_at,
675
+ updated_at: issue.updated_at,
676
+ },
677
+ comments: comments.map((c) => ({
678
+ id: c.id,
679
+ author: c.author,
680
+ author_kind: c.author_kind ?? "",
681
+ model: c.model ?? "",
682
+ upstream_comment_id: c.upstream_comment_id ?? null,
683
+ created_at: c.created_at,
684
+ body: c.body,
685
+ })),
686
+ });
687
+ }
628
688
  const evStatus = url.pathname.match(/^\/api\/v1\/repos\/([^/]+)\/([^/]+)\/issues\/(\d+)\/status$/);
629
689
  if (evStatus && req.method === "POST") {
630
690
  const [, owner, repo, numStr] = evStatus;
package/src/webhooks.ts CHANGED
@@ -329,7 +329,7 @@ interface IssueEventPayload {
329
329
 
330
330
  interface CommentEventPayload {
331
331
  event_id?: string;
332
- action: "created";
332
+ action: "created" | "edited";
333
333
  issue: PayloadIssue;
334
334
  comment: PayloadComment;
335
335
  repository: PayloadRepository;
@@ -487,9 +487,10 @@ function buildCommentPayload(
487
487
  origin: string,
488
488
  model?: string,
489
489
  labels: PayloadLabel[] = [],
490
+ action: "created" | "edited" = "created",
490
491
  ): CommentEventPayload {
491
492
  return {
492
- action: "created",
493
+ action,
493
494
  issue: buildIssue(issue, project, commentCount, origin, model, labels),
494
495
  comment: buildComment(issue, comment, project, origin),
495
496
  repository: buildRepository(project, origin, model, issue.runtime || undefined),
@@ -710,7 +711,8 @@ export async function emitCommentEvent(
710
711
  projectId: number,
711
712
  issueId: number,
712
713
  commentId: number,
713
- origin: string
714
+ origin: string,
715
+ action: "created" | "edited" = "created"
714
716
  ): Promise<void> {
715
717
  try {
716
718
  const project = await getProjectById(projectId);
@@ -726,7 +728,7 @@ export async function emitCommentEvent(
726
728
  const globalDefault = (await loadConfig()).defaultModel;
727
729
  const model = resolveModel(project.model, globalDefault, issue.model);
728
730
  const labels = await toPayloadLabels(issueId);
729
- const payload = buildCommentPayload(issue, comment, project, commentCount, origin, model, labels);
731
+ const payload = buildCommentPayload(issue, comment, project, commentCount, origin, model, labels, action);
730
732
  (payload as CommentEventPayload).event_id = randomUUID();
731
733
  if (authorUser) {
732
734
  payload.sender = buildUserFromRow(authorUser, origin);