@geminixiang/mikan 1.0.0-beta.80 → 1.0.0-beta.82

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.
Files changed (67) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/adapters/github/bot.d.ts.map +1 -1
  3. package/dist/adapters/github/bot.js +4 -4
  4. package/dist/adapters/github/bot.js.map +1 -1
  5. package/dist/adapters/github/client.d.ts +4 -0
  6. package/dist/adapters/github/client.d.ts.map +1 -1
  7. package/dist/adapters/github/client.js +41 -23
  8. package/dist/adapters/github/client.js.map +1 -1
  9. package/dist/adapters/github/github-ops.js +16 -12
  10. package/dist/adapters/github/github-ops.js.map +1 -1
  11. package/dist/adapters/slack/bot.d.ts.map +1 -1
  12. package/dist/adapters/slack/bot.js +6 -3
  13. package/dist/adapters/slack/bot.js.map +1 -1
  14. package/dist/adapters/web/server.d.ts +2 -0
  15. package/dist/adapters/web/server.d.ts.map +1 -1
  16. package/dist/adapters/web/server.js +11 -4
  17. package/dist/adapters/web/server.js.map +1 -1
  18. package/dist/adapters/web/session-view/portal.d.ts.map +1 -1
  19. package/dist/adapters/web/session-view/portal.js +84 -63
  20. package/dist/adapters/web/session-view/portal.js.map +1 -1
  21. package/dist/adapters/web/session-view/types.d.ts +2 -0
  22. package/dist/adapters/web/session-view/types.d.ts.map +1 -1
  23. package/dist/adapters/web/session-view/types.js.map +1 -1
  24. package/dist/env-manifest.d.ts +1 -0
  25. package/dist/env-manifest.d.ts.map +1 -1
  26. package/dist/env-manifest.js +7 -0
  27. package/dist/env-manifest.js.map +1 -1
  28. package/dist/harness/loop-guard.d.ts +10 -0
  29. package/dist/harness/loop-guard.d.ts.map +1 -0
  30. package/dist/harness/loop-guard.js +111 -0
  31. package/dist/harness/loop-guard.js.map +1 -0
  32. package/dist/harness/presenter.d.ts.map +1 -1
  33. package/dist/harness/presenter.js +159 -142
  34. package/dist/harness/presenter.js.map +1 -1
  35. package/dist/harness/prompt.d.ts +1 -1
  36. package/dist/harness/prompt.d.ts.map +1 -1
  37. package/dist/harness/prompt.js +14 -21
  38. package/dist/harness/prompt.js.map +1 -1
  39. package/dist/harness/run-events.d.ts +10 -0
  40. package/dist/harness/run-events.d.ts.map +1 -0
  41. package/dist/harness/run-events.js +129 -0
  42. package/dist/harness/run-events.js.map +1 -0
  43. package/dist/harness/runner.d.ts.map +1 -1
  44. package/dist/harness/runner.js +79 -49
  45. package/dist/harness/runner.js.map +1 -1
  46. package/dist/harness/session.d.ts +5 -0
  47. package/dist/harness/session.d.ts.map +1 -1
  48. package/dist/harness/session.js +71 -1
  49. package/dist/harness/session.js.map +1 -1
  50. package/dist/harness/tools/react.d.ts +1 -0
  51. package/dist/harness/tools/react.d.ts.map +1 -1
  52. package/dist/harness/tools/react.js +3 -2
  53. package/dist/harness/tools/react.js.map +1 -1
  54. package/dist/harness/types.d.ts +61 -0
  55. package/dist/harness/types.d.ts.map +1 -1
  56. package/dist/harness/types.js.map +1 -1
  57. package/dist/main.js +11 -8
  58. package/dist/main.js.map +1 -1
  59. package/dist/runtime/conversation-runtime.js +1 -0
  60. package/dist/runtime/conversation-runtime.js.map +1 -1
  61. package/dist/runtime/types.d.ts +2 -1
  62. package/dist/runtime/types.d.ts.map +1 -1
  63. package/dist/runtime/types.js.map +1 -1
  64. package/dist/types.d.ts +2 -1
  65. package/dist/types.d.ts.map +1 -1
  66. package/dist/types.js.map +1 -1
  67. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -9,6 +9,33 @@ any release.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [1.0.0-beta.82]
13
+
14
+ ### Changed
15
+
16
+ - mikan reacts `saluting_face` (eyes on GitHub) itself when a run starts its first work tool, instead of the model spending a separate round on the reaction; the model's `react` tool is left for background checks with nothing to report.
17
+ - mikan owns the `_Triggered by …_` signature on chat responses and replaces any signature line the model wrote, so user messages no longer carry a per-turn attribution instruction. The model is still asked to sign GitHub text it writes itself.
18
+ - The model reads the current time from each message's send time instead of running `date`.
19
+
20
+ ## [1.0.0-beta.81]
21
+
22
+ ### Added
23
+
24
+ - Stream every run of a session live in Session View: a run started from Slack or another chat platform now appears on an open page as it happens (user message, tool results, the streaming answer), then the timeline reloads. Page-sent messages use the same stream; thinking text and errors appear after the timeline reloads.
25
+ - Guard tool loops: repeating the same tool call with identical arguments earns a notice from the third call, is blocked from the fifth, and stops the run at the tenth; short repeating cycles of calls also earn a notice.
26
+ - Compact a session in the background after a successful run when its context nears the compaction threshold, so the next message does not wait for compaction.
27
+
28
+ ### Fixed
29
+
30
+ - Undo Slack's HTML escaping on incoming text: the model and the office log saw `&amp;&amp;`, `&lt;`, and `&gt;` where the user typed `&&`, `<`, and `>`.
31
+ - Keep the tool checklist visible while the final answer streams; it used to disappear until the answer finished.
32
+ - Stop an open Session View page from holding shutdown open; open live streams now close after a five-second grace, so a restart no longer waits for the process manager's kill timeout.
33
+ - Report a GitHub API request that returns an empty body where a resource is required with its method, path, and status, instead of failing later on a null value.
34
+
35
+ ### Security
36
+
37
+ - **Breaking (deploy):** The link server (Admin, Session View, and credential links) now listens on `127.0.0.1` even when `LINK_URL` is set; it used to listen on every interface, so portal tokens could travel in plain HTTP straight to `LINK_PORT` around the TLS reverse proxy. A reverse proxy on the same host (`reverse_proxy 127.0.0.1:8181`) keeps working unchanged. Set the new `LINK_HOST` (for example `0.0.0.0`) when the proxy runs on another host or in a separate network namespace.
38
+
12
39
  ## [1.0.0-beta.80]
13
40
 
14
41
  ### Fixed
@@ -1 +1 @@
1
- {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/github/bot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AAcxB,OAAO,EAAgC,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAQ1E,OAAO,KAAK,EAAU,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE3E,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EAKf,eAAe,EAChB,MAAM,YAAY,CAAC;AA+CpB,eAAO,MAAM,wBAAwB,YAAa,MAAM,KAAG,MAAoC,CAAC;AAwEhG,qBAAa,kBAAmB,YAAW,YAAY;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,eAAe,CAA0D;IACjF,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,gBAAgB,CAA+B;IAEvD,YAAY,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,SAAS,EAWtF;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA0D3B;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAa1B;IAEK,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQhE;IAEK,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5E;IAEK,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBlF;IAED,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAe9C;IAED,gBAAgB,IAAI,aAAa,CAWhC;IAEK,WAAW,CAAC,GAAG,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAK3E;IAEK,aAAa,CAAC,GAAG,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhF;IAED,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAErD;IAED,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAErE;IAED,OAAO,CAAC,QAAQ;IAShB,WAAW,CAAC,UAAU,SAA2B,GAAG,IAAI,CAYvD;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAiB1B;YAEa,gBAAgB;YAYhB,QAAQ;YAqDR,WAAW;IA4BzB,OAAO,CAAC,aAAa;IAarB,iBAAiB,IAAI,eAAe,CAYnC;IAED,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,eAAe;YAIT,oBAAoB;YA0BpB,cAAc;YAkEd,mBAAmB;YAgBnB,mBAAmB;YAqBnB,mBAAmB;YA+BnB,eAAe;YA6Bf,eAAe;CA8B9B"}
1
+ {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/github/bot.ts"],"names":[],"mappings":"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"}
@@ -53,6 +53,7 @@ const GITHUB_REACTIONS = {
53
53
  tada: "hooray",
54
54
  rocket: "rocket",
55
55
  eyes: "eyes",
56
+ saluting_face: "eyes",
56
57
  };
57
58
  function parseRepoList(repos) {
58
59
  return repos.map((entry) => {
@@ -458,7 +459,7 @@ export class GithubMessagingBot {
458
459
  persistentTopLevel: true,
459
460
  });
460
461
  const messageText = item.review
461
- ? await this.formatReviewMessage(item, cleanedText)
462
+ ? await this.formatReviewMessage(item.ref, item.review, cleanedText)
462
463
  : cleanedText;
463
464
  const eventBase = createConversationEvent({
464
465
  platform: "github",
@@ -512,8 +513,7 @@ export class GithubMessagingBot {
512
513
  await this.ensureRepoClone(item.ref, conversationId, isPr);
513
514
  }
514
515
  }
515
- async formatReviewMessage(item, cleanedText) {
516
- const review = item.review;
516
+ async formatReviewMessage(ref, review, cleanedText) {
517
517
  const location = review.line !== null ? `${review.path}:${review.line}` : review.path;
518
518
  const parts = [`[PR review comment ${githubReviewCommentTs(review.commentId)} on ${location}]`];
519
519
  if (review.diffHunk) {
@@ -523,7 +523,7 @@ export class GithubMessagingBot {
523
523
  parts.push(`\`\`\`diff\n${hunk}\n\`\`\``);
524
524
  }
525
525
  if (review.inReplyToId !== undefined) {
526
- const turns = await this.reviewThreadContext(item.ref, review.inReplyToId, review.commentId);
526
+ const turns = await this.reviewThreadContext(ref, review.inReplyToId, review.commentId);
527
527
  if (turns.length > 0) {
528
528
  parts.push(`Thread so far:\n${turns.join("\n")}`);
529
529
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bot.js","sourceRoot":"","sources":["../../../src/adapters/github/bot.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { Type } from \"typebox\";\nimport type {\n MessagingBot,\n MessagingEventHandler,\n MessagingInfo,\n ConversationEvent,\n} from \"../../types.js\";\nimport * as log from \"../../log.js\";\nimport { ensureDirExists, readJsonSchemaFileIfExists } from \"../../file-guards.js\";\nimport { atomicWritePrivateFile } from \"../../file-guards.js\";\nimport { resolveChatSessionKey } from \"../../sessions/session-key.js\";\nimport {\n appendBotResponseLog,\n appendChannelLog,\n MessagingEventQueue,\n splitText,\n} from \"../shared.js\";\nimport { matchMagicWord, processMessageIntake } from \"../intake.js\";\nimport { GithubClient, GITHUB_MAX_COMMENT_LENGTH, githubRetry } from \"./client.js\";\nimport { createGithubAdapters } from \"./context.js\";\nimport { fetchIsPr, fetchPrHeadBranch, GithubOps } from \"./github-ops.js\";\nimport { cloneRepo, conversationRepoDir } from \"./repo.js\";\nimport {\n buildGithubConversationId,\n createConversationEvent,\n createOfficeAddress,\n parseGithubConversationId,\n} from \"../../office/index.js\";\nimport type { Office, GithubConversationRef } from \"../../office/types.js\";\nimport { GITHUB_ISSUE_BODY_TS, githubReviewCommentTs, parseReviewCommentTs } from \"./ids.js\";\nimport type {\n GithubApi,\n GithubBotConfig,\n GithubEvent,\n GithubIssue,\n GithubReactionContent,\n GithubRepoRef,\n GithubSyncState,\n} from \"./types.js\";\nimport { errorMessage } from \"../../unknown-values.js\";\n\nconst SyncStateSchema = Type.Object({\n repos: Type.Record(\n Type.String(),\n Type.Object({\n baseline: Type.String(),\n cursor: Type.String(),\n seenComments: Type.Array(Type.Number()),\n seenIssues: Type.Array(Type.Number()),\n seenReviewComments: Type.Optional(Type.Array(Type.Number())),\n }),\n ),\n});\n\nconst POLL_OVERLAP_MS = 5 * 60 * 1000;\n\nconst MAX_SEEN_IDS = 5000;\n\nconst REQUEST_POLL_DEBOUNCE_MS = 1500;\n\nconst PERMISSION_RANK = {\n none: 0,\n read: 1,\n triage: 2,\n write: 3,\n maintain: 4,\n admin: 5,\n};\n\nconst REQUIRED_TRIGGER_RANK = PERMISSION_RANK.write;\n\nfunction rankOfPermission(name: string): number {\n return PERMISSION_RANK[name as keyof typeof PERMISSION_RANK] ?? 0;\n}\n\nconst PERMISSION_CACHE_TTL_MS = 5 * 60 * 1000;\n\ninterface RepoWatermark {\n baseline: string;\n cursor: string;\n seenComments: Set<number>;\n seenIssues: Set<number>;\n seenReviewComments: Set<number>;\n}\n\nexport const formatGithubContinuation = (partNum: number): string => `*(continued ${partNum})*`;\n\nconst GITHUB_REACTIONS: Record<string, GithubReactionContent> = {\n \"+1\": \"+1\",\n thumbsup: \"+1\",\n \"-1\": \"-1\",\n thumbsdown: \"-1\",\n laugh: \"laugh\",\n smile: \"laugh\",\n confused: \"confused\",\n heart: \"heart\",\n hooray: \"hooray\",\n tada: \"hooray\",\n rocket: \"rocket\",\n eyes: \"eyes\",\n};\n\ninterface IncomingItem {\n ref: GithubConversationRef;\n ts: string;\n user: string;\n text: string;\n createdAt: string;\n isPr?: boolean;\n review?: {\n commentId: number;\n path: string;\n line: number | null;\n diffHunk: string;\n inReplyToId?: number;\n };\n}\n\nfunction parseRepoList(repos: string[]): GithubRepoRef[] {\n return repos.map((entry) => {\n const [owner, repo, ...rest] = entry.split(\"/\");\n if (!owner || !repo || rest.length > 0) {\n throw new Error(`Invalid GITHUB_REPOS entry (expected owner/repo): ${entry}`);\n }\n return { owner: owner.toLowerCase(), repo: repo.toLowerCase() };\n });\n}\n\nfunction pruneSeen(seen: Set<number>): void {\n if (seen.size <= MAX_SEEN_IDS) return;\n let toDrop = seen.size - MAX_SEEN_IDS / 2;\n for (const id of seen) {\n if (toDrop-- <= 0) break;\n seen.delete(id);\n }\n}\n\nfunction issueNumberFromUrl(issueUrl: string): number {\n const match = /\\/issues\\/(\\d+)$/.exec(issueUrl);\n if (!match) {\n throw new Error(`Cannot parse issue number from ${issueUrl}`);\n }\n return Number(match[1]);\n}\n\nfunction prNumberFromUrl(pullRequestUrl: string): number {\n const match = /\\/pulls\\/(\\d+)$/.exec(pullRequestUrl);\n if (!match) {\n throw new Error(`Cannot parse PR number from ${pullRequestUrl}`);\n }\n return Number(match[1]);\n}\n\nconst MAX_DIFF_HUNK_CHARS = 1500;\nconst MAX_THREAD_TURNS = 10;\nconst MAX_THREAD_TURN_CHARS = 500;\n\nexport class GithubMessagingBot implements MessagingBot {\n private readonly client: GithubApi;\n private readonly handler: MessagingEventHandler;\n private readonly config: GithubBotConfig;\n readonly ops: GithubOps;\n private appSlug: string | null = null;\n private botEmail: string | null = null;\n private watchedRepos: GithubRepoRef[] = [];\n private queues = new Map<string, MessagingEventQueue>();\n private repoState = new Map<string, RepoWatermark>();\n private permissionCache = new Map<string, { rank: number; expiresAt: number }>();\n private stopped = true;\n private stopping = false;\n private activePoll: Promise<void> | null = null;\n private pollPending = false;\n private pollIntervalTimer: NodeJS.Timeout | null = null;\n private requestPollTimer: NodeJS.Timeout | null = null;\n\n constructor(handler: MessagingEventHandler, config: GithubBotConfig, client?: GithubApi) {\n this.handler = handler;\n this.config = config;\n this.client =\n client ??\n new GithubClient({\n appId: config.appId,\n privateKey: config.privateKey,\n installationId: config.installationId,\n });\n this.ops = new GithubOps(this.client, { workspace: config.workspace });\n }\n\n async start(): Promise<void> {\n this.stopped = false;\n this.stopping = false;\n this.appSlug = await this.client.getAppSlug();\n try {\n const botUserId = await this.client.getUserId(`${this.appSlug}[bot]`);\n this.botEmail = `${botUserId}+${this.appSlug}[bot]@users.noreply.github.com`;\n } catch {\n this.botEmail = `${this.appSlug}[bot]@users.noreply.github.com`;\n }\n this.watchedRepos =\n this.config.repos.length > 0\n ? parseRepoList(this.config.repos)\n : (await this.client.listInstallationRepositories()).map((repository) => ({\n owner: repository.owner.login.toLowerCase(),\n repo: repository.name.toLowerCase(),\n }));\n if (this.watchedRepos.length === 0) {\n log.logWarning(\"GitHub: installation has no repositories; nothing to poll\");\n }\n\n const persisted = this.loadSyncState();\n const now = new Date().toISOString();\n for (const repo of this.watchedRepos) {\n const repoKey = `${repo.owner}/${repo.repo}`;\n const saved = persisted?.repos[repoKey];\n this.repoState.set(\n repoKey,\n saved\n ? {\n baseline: saved.baseline,\n cursor: saved.cursor,\n seenComments: new Set(saved.seenComments),\n seenIssues: new Set(saved.seenIssues),\n seenReviewComments: new Set(saved.seenReviewComments ?? []),\n }\n : {\n baseline: now,\n cursor: now,\n seenComments: new Set(),\n seenIssues: new Set(),\n seenReviewComments: new Set(),\n },\n );\n }\n this.persistSyncState();\n if (this.stopping) return;\n\n this.stopped = false;\n this.pollIntervalTimer = setInterval(() => {\n void this.poll();\n }, this.config.pollIntervalMs);\n this.pollIntervalTimer.unref();\n\n log.logConnected(\"GitHub\");\n log.logInfo(\n `GitHub bot started as @${this.appSlug}[bot], polling ${this.watchedRepos.length} repo(s) every ${Math.round(this.config.pollIntervalMs / 1000)}s`,\n );\n }\n\n async stop(): Promise<void> {\n this.stopping = true;\n this.pollPending = false;\n if (this.pollIntervalTimer) clearInterval(this.pollIntervalTimer);\n if (this.requestPollTimer) clearTimeout(this.requestPollTimer);\n this.pollIntervalTimer = null;\n this.requestPollTimer = null;\n try {\n if (this.activePoll) await this.activePoll;\n } finally {\n this.stopped = true;\n await Promise.all([...this.queues.values()].map((queue) => queue.close()));\n }\n }\n\n async postMessage(channel: string, text: string): Promise<string> {\n const ref = parseGithubConversationId(channel);\n const parts = splitText(text, GITHUB_MAX_COMMENT_LENGTH, formatGithubContinuation);\n const firstId = await this.postComment(ref, parts[0] ?? text);\n for (const part of parts.slice(1)) {\n await this.postComment(ref, part);\n }\n return String(firstId);\n }\n\n async updateMessage(channel: string, ts: string, text: string): Promise<void> {\n const ref = parseGithubConversationId(channel);\n await githubRetry(() => this.client.updateIssueComment(ref.owner, ref.repo, Number(ts), text));\n }\n\n async addReaction(channel: string, messageTs: string, emoji: string): Promise<void> {\n const ref = parseGithubConversationId(channel);\n const content = GITHUB_REACTIONS[emoji.replace(/^:|:$/g, \"\")];\n if (!content) {\n throw new Error(\n `GitHub does not support reaction '${emoji}' (supported: ${Object.keys(GITHUB_REACTIONS).join(\", \")})`,\n );\n }\n const reviewCommentId = parseReviewCommentTs(messageTs);\n await githubRetry(() => {\n if (messageTs === GITHUB_ISSUE_BODY_TS) {\n return this.client.createIssueReaction(ref.owner, ref.repo, ref.number, content);\n }\n if (reviewCommentId !== null) {\n return this.client.createReviewCommentReaction(\n ref.owner,\n ref.repo,\n reviewCommentId,\n content,\n );\n }\n return this.client.createCommentReaction(ref.owner, ref.repo, Number(messageTs), content);\n });\n }\n\n enqueueEvent(event: ConversationEvent): boolean {\n if (this.stopped) return false;\n const conversationId = event.address.conversationId;\n const queue = this.getQueue(conversationId);\n if (queue.size() >= 5) {\n log.logWarning(\n `Event queue full for ${conversationId}, discarding: ${event.text.substring(0, 50)}`,\n );\n return false;\n }\n log.logInfo(`Enqueueing event for ${conversationId}: ${event.text.substring(0, 50)}`);\n return queue.enqueue(() => {\n const context = createGithubAdapters(event as GithubEvent, this);\n return this.handler.handleEvent(event, this, context);\n });\n }\n\n getMessagingInfo(): MessagingInfo {\n return {\n name: \"github\",\n trustModel: \"open-trigger\",\n formattingGuide:\n \"## GitHub Formatting (GitHub Flavored Markdown)\\n\" +\n \"Standard Markdown plus tables, task lists, fenced code blocks, and ```suggestion blocks.\\n\" +\n \"Reference issues/PRs as #123 and users as @login (mentions notify people — use sparingly).\",\n channels: [],\n users: [],\n };\n }\n\n async postComment(ref: GithubConversationRef, text: string): Promise<number> {\n const comment = await githubRetry(() =>\n this.client.createIssueComment(ref.owner, ref.repo, ref.number, text),\n );\n return comment.id;\n }\n\n async deleteComment(ref: GithubConversationRef, commentId: number): Promise<void> {\n await githubRetry(() => this.client.deleteIssueComment(ref.owner, ref.repo, commentId));\n }\n\n logToFile(conversationId: string, entry: object): void {\n appendChannelLog(this.office(conversationId), entry);\n }\n\n logBotResponse(conversationId: string, text: string, ts: string): void {\n appendBotResponseLog(this.office(conversationId), text, ts);\n }\n\n private getQueue(conversationId: string): MessagingEventQueue {\n let queue = this.queues.get(conversationId);\n if (!queue) {\n queue = new MessagingEventQueue(\"GitHub\");\n this.queues.set(conversationId, queue);\n }\n return queue;\n }\n\n requestPoll(debounceMs = REQUEST_POLL_DEBOUNCE_MS): void {\n if (this.stopped || this.stopping) return;\n if (this.activePoll) {\n this.pollPending = true;\n return;\n }\n if (this.requestPollTimer) return;\n this.requestPollTimer = setTimeout(() => {\n this.requestPollTimer = null;\n void this.poll();\n }, debounceMs);\n this.requestPollTimer.unref();\n }\n\n async poll(): Promise<void> {\n if (this.stopped || this.stopping) return;\n if (this.activePoll) {\n this.pollPending = true;\n return;\n }\n const activePoll = this.pollWatchedRepos();\n this.activePoll = activePoll;\n try {\n await activePoll;\n } finally {\n this.activePoll = null;\n if (this.pollPending) {\n this.pollPending = false;\n this.requestPoll();\n }\n }\n }\n\n private async pollWatchedRepos(): Promise<void> {\n let changed = false;\n for (const repo of this.watchedRepos) {\n try {\n changed = (await this.pollRepo(repo)) || changed;\n } catch (err) {\n log.logWarning(`GitHub poll failed for ${repo.owner}/${repo.repo}`, errorMessage(err));\n }\n }\n if (changed) this.persistSyncState();\n }\n\n private async pollRepo(repo: GithubRepoRef): Promise<boolean> {\n const repoKey = `${repo.owner}/${repo.repo}`;\n const state = this.repoState.get(repoKey);\n if (!state) return false;\n const since = new Date(Date.parse(state.cursor) - POLL_OVERLAP_MS).toISOString();\n let changed = false;\n\n const issues = (await this.client.listIssuesSince(repo.owner, repo.repo, since)) ?? [];\n changed =\n (await this.advanceFeed(state, state.seenIssues, issues, (issue) => ({\n ref: { ...repo, number: issue.number },\n ts: GITHUB_ISSUE_BODY_TS,\n user: issue.user.login,\n text: `# ${issue.title}\\n\\n${issue.body ?? \"\"}`.trim(),\n createdAt: issue.created_at,\n isPr: Boolean(issue.pull_request),\n }))) || changed;\n\n const comments = (await this.client.listIssueCommentsSince(repo.owner, repo.repo, since)) ?? [];\n changed =\n (await this.advanceFeed(state, state.seenComments, comments, (comment) => ({\n ref: { ...repo, number: issueNumberFromUrl(comment.issue_url) },\n ts: String(comment.id),\n user: comment.user.login,\n text: comment.body,\n createdAt: comment.created_at,\n }))) || changed;\n\n const reviewComments =\n (await this.client.listPullReviewCommentsSince(repo.owner, repo.repo, since)) ?? [];\n changed =\n (await this.advanceFeed(state, state.seenReviewComments, reviewComments, (comment) => ({\n ref: { ...repo, number: prNumberFromUrl(comment.pull_request_url) },\n ts: githubReviewCommentTs(comment.id),\n user: comment.user.login,\n text: comment.body,\n createdAt: comment.created_at,\n isPr: true,\n review: {\n commentId: comment.id,\n path: comment.path,\n line: comment.line,\n diffHunk: comment.diff_hunk,\n inReplyToId: comment.in_reply_to_id,\n },\n }))) || changed;\n\n pruneSeen(state.seenComments);\n pruneSeen(state.seenIssues);\n pruneSeen(state.seenReviewComments);\n return changed;\n }\n\n private async advanceFeed<\n T extends {\n id: number;\n created_at: string;\n updated_at: string;\n user: { login: string; type: string };\n },\n >(\n state: RepoWatermark,\n seen: Set<number>,\n items: T[],\n toIncoming: (item: T) => IncomingItem,\n ): Promise<boolean> {\n let changed = false;\n for (const item of items) {\n if (item.updated_at > state.cursor) {\n state.cursor = item.updated_at;\n changed = true;\n }\n if (item.created_at < state.baseline || seen.has(item.id)) continue;\n seen.add(item.id);\n changed = true;\n if (item.user.type === \"Bot\") continue;\n await this.handleIncoming(toIncoming(item));\n }\n return changed;\n }\n\n private loadSyncState(): GithubSyncState | undefined {\n try {\n return readJsonSchemaFileIfExists(\n this.config.syncStatePath,\n SyncStateSchema,\n (detail) => `Malformed GitHub sync state at ${this.config.syncStatePath}: ${detail}`,\n );\n } catch (err) {\n log.logWarning(\"GitHub: ignoring unreadable sync state\", errorMessage(err));\n return undefined;\n }\n }\n\n syncStateSnapshot(): GithubSyncState {\n const state: GithubSyncState = { repos: {} };\n for (const [repoKey, watermark] of this.repoState) {\n state.repos[repoKey] = {\n baseline: watermark.baseline,\n cursor: watermark.cursor,\n seenComments: [...watermark.seenComments],\n seenIssues: [...watermark.seenIssues],\n seenReviewComments: [...watermark.seenReviewComments],\n };\n }\n return state;\n }\n\n private persistSyncState(): void {\n ensureDirExists(dirname(this.config.syncStatePath));\n atomicWritePrivateFile(this.config.syncStatePath, JSON.stringify(this.syncStateSnapshot()));\n }\n\n private mentionPattern(): RegExp | null {\n return this.appSlug ? new RegExp(`@${this.appSlug}(?![\\\\w-])`, \"gi\") : null;\n }\n\n private isMentioned(text: string): boolean {\n const pattern = this.mentionPattern();\n return pattern ? pattern.test(text) : false;\n }\n\n private stripMention(text: string): string {\n const pattern = this.mentionPattern();\n return (pattern ? text.replace(pattern, \"\") : text).trim();\n }\n\n private office(conversationId: string): Office {\n return this.config.workspace.office(createOfficeAddress(\"github\", conversationId));\n }\n\n private isParticipating(conversationId: string): boolean {\n return existsSync(this.office(conversationId).logPath);\n }\n\n private async hasTriggerPermission(ref: GithubConversationRef, user: string): Promise<boolean> {\n const cacheKey = `${ref.owner}/${ref.repo}#${user}`;\n const cached = this.permissionCache.get(cacheKey);\n if (cached && Date.now() < cached.expiresAt) {\n return cached.rank >= REQUIRED_TRIGGER_RANK;\n }\n let rank: number;\n try {\n const role = await githubRetry(() =>\n this.client.getCollaboratorPermission(ref.owner, ref.repo, user),\n );\n rank = Math.max(rankOfPermission(role.role_name ?? \"\"), rankOfPermission(role.permission));\n } catch (err) {\n log.logWarning(\n `GitHub: permission lookup failed for ${user} on ${ref.owner}/${ref.repo}; denying trigger`,\n errorMessage(err),\n );\n return false;\n }\n this.permissionCache.set(cacheKey, {\n rank,\n expiresAt: Date.now() + PERMISSION_CACHE_TTL_MS,\n });\n return rank >= REQUIRED_TRIGGER_RANK;\n }\n\n private async handleIncoming(item: IncomingItem): Promise<void> {\n const conversationId = buildGithubConversationId(item.ref);\n const mentioned = this.isMentioned(item.text);\n const participating = this.isParticipating(conversationId);\n if (!mentioned && !participating) return;\n\n if (!(await this.hasTriggerPermission(item.ref, item.user))) {\n log.logInfo(\n `GitHub: ignoring ${conversationId} comment from ${item.user} (below write permission)`,\n );\n return;\n }\n\n const cleanedText = this.stripMention(item.text);\n const sessionKey = resolveChatSessionKey({\n conversationId,\n conversationKind: \"shared\",\n messageId: item.ts,\n persistentTopLevel: true,\n });\n\n const messageText = item.review\n ? await this.formatReviewMessage(item, cleanedText)\n : cleanedText;\n\n const eventBase = createConversationEvent({\n platform: \"github\",\n type: item.ts === GITHUB_ISSUE_BODY_TS ? \"issue\" : \"message\",\n conversationId,\n conversationKind: \"shared\",\n ts: item.ts,\n sessionKey,\n user: item.user,\n userName: item.user,\n text: messageText,\n }) as GithubEvent;\n\n await processMessageIntake({\n eventBase,\n addressed: true,\n magicWord: { text: cleanedText, addressed: mentioned, scopeFallback: \"never\" },\n busyPolicy: \"queue\",\n logEntryBase: {\n date: item.createdAt,\n ts: item.ts,\n user: item.user,\n userName: item.user,\n text: messageText,\n isMessagingBot: false,\n },\n log: (entry) => {\n if (!participating && matchMagicWord(cleanedText) === \"stop\") return;\n this.logToFile(conversationId, entry);\n },\n processAttachments: async () => {\n await this.prepareConversation(item, conversationId, participating);\n return [];\n },\n queueKey: conversationId,\n enqueue: (queueKey, work) => this.getQueue(queueKey).enqueue(work),\n handler: this.handler,\n bot: this,\n createContext: (event) => createGithubAdapters(event, this),\n });\n }\n\n private async prepareConversation(\n item: IncomingItem,\n conversationId: string,\n participating: boolean,\n ): Promise<void> {\n let isPrHint = item.isPr;\n if (!participating && item.ts !== GITHUB_ISSUE_BODY_TS) {\n const issue = await this.logIssueContext(item.ref, conversationId, item.createdAt);\n if (issue && isPrHint === undefined) isPrHint = Boolean(issue.pull_request);\n }\n if (!existsSync(conversationRepoDir(this.office(conversationId)))) {\n const isPr = isPrHint ?? (await fetchIsPr(this.client, item.ref));\n await this.ensureRepoClone(item.ref, conversationId, isPr);\n }\n }\n\n private async formatReviewMessage(item: IncomingItem, cleanedText: string): Promise<string> {\n const review = item.review!;\n const location = review.line !== null ? `${review.path}:${review.line}` : review.path;\n const parts = [`[PR review comment ${githubReviewCommentTs(review.commentId)} on ${location}]`];\n if (review.diffHunk) {\n const hunk =\n review.diffHunk.length > MAX_DIFF_HUNK_CHARS\n ? `…${review.diffHunk.slice(-MAX_DIFF_HUNK_CHARS)}`\n : review.diffHunk;\n parts.push(`\\`\\`\\`diff\\n${hunk}\\n\\`\\`\\``);\n }\n if (review.inReplyToId !== undefined) {\n const turns = await this.reviewThreadContext(item.ref, review.inReplyToId, review.commentId);\n if (turns.length > 0) {\n parts.push(`Thread so far:\\n${turns.join(\"\\n\")}`);\n }\n }\n parts.push(cleanedText);\n return parts.join(\"\\n\");\n }\n\n private async reviewThreadContext(\n ref: GithubConversationRef,\n rootId: number,\n beforeId: number,\n ): Promise<string[]> {\n try {\n const all = await githubRetry(() =>\n this.client.listPullReviewComments(ref.owner, ref.repo, ref.number),\n );\n return all\n .filter(\n (comment) =>\n (comment.id === rootId || comment.in_reply_to_id === rootId) && comment.id < beforeId,\n )\n .slice(-MAX_THREAD_TURNS)\n .map((comment) => {\n const body =\n comment.body.length > MAX_THREAD_TURN_CHARS\n ? `${comment.body.slice(0, MAX_THREAD_TURN_CHARS)}…`\n : comment.body;\n return `@${comment.user.login}: ${body}`;\n });\n } catch (err) {\n log.logWarning(\n `GitHub: could not fetch review thread context for ${ref.owner}/${ref.repo}#${ref.number}`,\n errorMessage(err),\n );\n return [];\n }\n }\n\n private async logIssueContext(\n ref: GithubConversationRef,\n conversationId: string,\n triggerCreatedAt: string,\n ): Promise<GithubIssue | null> {\n let issue: GithubIssue;\n try {\n issue = await githubRetry(() => this.client.getIssue(ref.owner, ref.repo, ref.number));\n } catch (err) {\n log.logWarning(\n `GitHub: could not fetch issue context for ${conversationId}`,\n errorMessage(err),\n );\n return null;\n }\n const triggerMs = Date.parse(triggerCreatedAt);\n const contextDate = new Date((Number.isFinite(triggerMs) ? triggerMs : Date.now()) - 1000);\n this.logToFile(conversationId, {\n date: contextDate.toISOString(),\n ts: GITHUB_ISSUE_BODY_TS,\n user: issue.user.login,\n userName: issue.user.login,\n text: `# ${issue.title}\\n\\n${issue.body ?? \"\"}`.trim(),\n attachments: [],\n isMessagingBot: false,\n });\n return issue;\n }\n\n private async ensureRepoClone(\n ref: GithubConversationRef,\n conversationId: string,\n isPr: boolean,\n ): Promise<void> {\n const office = this.office(conversationId);\n const dir = conversationRepoDir(office);\n if (existsSync(dir)) return;\n try {\n office.ensure();\n const token = await this.client.createScopedInstallationToken(ref.repo, {\n contents: \"read\",\n });\n const prHeadBranch = isPr ? await fetchPrHeadBranch(this.client, ref) : undefined;\n await cloneRepo({\n url: `https://github.com/${ref.owner}/${ref.repo}.git`,\n dir,\n token,\n botLogin: `${this.appSlug}[bot]`,\n botEmail: this.botEmail ?? `${this.appSlug}[bot]@users.noreply.github.com`,\n prNumber: isPr ? ref.number : undefined,\n prHeadBranch,\n });\n log.logInfo(\n `[${conversationId}] Cloned ${ref.owner}/${ref.repo}${isPr ? ` and checked out PR #${ref.number} head as ${prHeadBranch ?? `pr-${ref.number}`}` : \"\"}`,\n );\n } catch (err) {\n log.logWarning(`GitHub: repo clone failed for ${conversationId}`, errorMessage(err));\n }\n }\n}\n"]}
1
+ {"version":3,"file":"bot.js","sourceRoot":"","sources":["../../../src/adapters/github/bot.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { Type } from \"typebox\";\nimport type {\n MessagingBot,\n MessagingEventHandler,\n MessagingInfo,\n ConversationEvent,\n} from \"../../types.js\";\nimport * as log from \"../../log.js\";\nimport { ensureDirExists, readJsonSchemaFileIfExists } from \"../../file-guards.js\";\nimport { atomicWritePrivateFile } from \"../../file-guards.js\";\nimport { resolveChatSessionKey } from \"../../sessions/session-key.js\";\nimport {\n appendBotResponseLog,\n appendChannelLog,\n MessagingEventQueue,\n splitText,\n} from \"../shared.js\";\nimport { matchMagicWord, processMessageIntake } from \"../intake.js\";\nimport { GithubClient, GITHUB_MAX_COMMENT_LENGTH, githubRetry } from \"./client.js\";\nimport { createGithubAdapters } from \"./context.js\";\nimport { fetchIsPr, fetchPrHeadBranch, GithubOps } from \"./github-ops.js\";\nimport { cloneRepo, conversationRepoDir } from \"./repo.js\";\nimport {\n buildGithubConversationId,\n createConversationEvent,\n createOfficeAddress,\n parseGithubConversationId,\n} from \"../../office/index.js\";\nimport type { Office, GithubConversationRef } from \"../../office/types.js\";\nimport { GITHUB_ISSUE_BODY_TS, githubReviewCommentTs, parseReviewCommentTs } from \"./ids.js\";\nimport type {\n GithubApi,\n GithubBotConfig,\n GithubEvent,\n GithubIssue,\n GithubReactionContent,\n GithubRepoRef,\n GithubSyncState,\n} from \"./types.js\";\nimport { errorMessage } from \"../../unknown-values.js\";\n\nconst SyncStateSchema = Type.Object({\n repos: Type.Record(\n Type.String(),\n Type.Object({\n baseline: Type.String(),\n cursor: Type.String(),\n seenComments: Type.Array(Type.Number()),\n seenIssues: Type.Array(Type.Number()),\n seenReviewComments: Type.Optional(Type.Array(Type.Number())),\n }),\n ),\n});\n\nconst POLL_OVERLAP_MS = 5 * 60 * 1000;\n\nconst MAX_SEEN_IDS = 5000;\n\nconst REQUEST_POLL_DEBOUNCE_MS = 1500;\n\nconst PERMISSION_RANK = {\n none: 0,\n read: 1,\n triage: 2,\n write: 3,\n maintain: 4,\n admin: 5,\n};\n\nconst REQUIRED_TRIGGER_RANK = PERMISSION_RANK.write;\n\nfunction rankOfPermission(name: string): number {\n return PERMISSION_RANK[name as keyof typeof PERMISSION_RANK] ?? 0;\n}\n\nconst PERMISSION_CACHE_TTL_MS = 5 * 60 * 1000;\n\ninterface RepoWatermark {\n baseline: string;\n cursor: string;\n seenComments: Set<number>;\n seenIssues: Set<number>;\n seenReviewComments: Set<number>;\n}\n\nexport const formatGithubContinuation = (partNum: number): string => `*(continued ${partNum})*`;\n\nconst GITHUB_REACTIONS: Record<string, GithubReactionContent> = {\n \"+1\": \"+1\",\n thumbsup: \"+1\",\n \"-1\": \"-1\",\n thumbsdown: \"-1\",\n laugh: \"laugh\",\n smile: \"laugh\",\n confused: \"confused\",\n heart: \"heart\",\n hooray: \"hooray\",\n tada: \"hooray\",\n rocket: \"rocket\",\n eyes: \"eyes\",\n saluting_face: \"eyes\",\n};\n\ninterface IncomingItem {\n ref: GithubConversationRef;\n ts: string;\n user: string;\n text: string;\n createdAt: string;\n isPr?: boolean;\n review?: {\n commentId: number;\n path: string;\n line: number | null;\n diffHunk: string;\n inReplyToId?: number;\n };\n}\n\nfunction parseRepoList(repos: string[]): GithubRepoRef[] {\n return repos.map((entry) => {\n const [owner, repo, ...rest] = entry.split(\"/\");\n if (!owner || !repo || rest.length > 0) {\n throw new Error(`Invalid GITHUB_REPOS entry (expected owner/repo): ${entry}`);\n }\n return { owner: owner.toLowerCase(), repo: repo.toLowerCase() };\n });\n}\n\nfunction pruneSeen(seen: Set<number>): void {\n if (seen.size <= MAX_SEEN_IDS) return;\n let toDrop = seen.size - MAX_SEEN_IDS / 2;\n for (const id of seen) {\n if (toDrop-- <= 0) break;\n seen.delete(id);\n }\n}\n\nfunction issueNumberFromUrl(issueUrl: string): number {\n const match = /\\/issues\\/(\\d+)$/.exec(issueUrl);\n if (!match) {\n throw new Error(`Cannot parse issue number from ${issueUrl}`);\n }\n return Number(match[1]);\n}\n\nfunction prNumberFromUrl(pullRequestUrl: string): number {\n const match = /\\/pulls\\/(\\d+)$/.exec(pullRequestUrl);\n if (!match) {\n throw new Error(`Cannot parse PR number from ${pullRequestUrl}`);\n }\n return Number(match[1]);\n}\n\nconst MAX_DIFF_HUNK_CHARS = 1500;\nconst MAX_THREAD_TURNS = 10;\nconst MAX_THREAD_TURN_CHARS = 500;\n\nexport class GithubMessagingBot implements MessagingBot {\n private readonly client: GithubApi;\n private readonly handler: MessagingEventHandler;\n private readonly config: GithubBotConfig;\n readonly ops: GithubOps;\n private appSlug: string | null = null;\n private botEmail: string | null = null;\n private watchedRepos: GithubRepoRef[] = [];\n private queues = new Map<string, MessagingEventQueue>();\n private repoState = new Map<string, RepoWatermark>();\n private permissionCache = new Map<string, { rank: number; expiresAt: number }>();\n private stopped = true;\n private stopping = false;\n private activePoll: Promise<void> | null = null;\n private pollPending = false;\n private pollIntervalTimer: NodeJS.Timeout | null = null;\n private requestPollTimer: NodeJS.Timeout | null = null;\n\n constructor(handler: MessagingEventHandler, config: GithubBotConfig, client?: GithubApi) {\n this.handler = handler;\n this.config = config;\n this.client =\n client ??\n new GithubClient({\n appId: config.appId,\n privateKey: config.privateKey,\n installationId: config.installationId,\n });\n this.ops = new GithubOps(this.client, { workspace: config.workspace });\n }\n\n async start(): Promise<void> {\n this.stopped = false;\n this.stopping = false;\n this.appSlug = await this.client.getAppSlug();\n try {\n const botUserId = await this.client.getUserId(`${this.appSlug}[bot]`);\n this.botEmail = `${botUserId}+${this.appSlug}[bot]@users.noreply.github.com`;\n } catch {\n this.botEmail = `${this.appSlug}[bot]@users.noreply.github.com`;\n }\n this.watchedRepos =\n this.config.repos.length > 0\n ? parseRepoList(this.config.repos)\n : (await this.client.listInstallationRepositories()).map((repository) => ({\n owner: repository.owner.login.toLowerCase(),\n repo: repository.name.toLowerCase(),\n }));\n if (this.watchedRepos.length === 0) {\n log.logWarning(\"GitHub: installation has no repositories; nothing to poll\");\n }\n\n const persisted = this.loadSyncState();\n const now = new Date().toISOString();\n for (const repo of this.watchedRepos) {\n const repoKey = `${repo.owner}/${repo.repo}`;\n const saved = persisted?.repos[repoKey];\n this.repoState.set(\n repoKey,\n saved\n ? {\n baseline: saved.baseline,\n cursor: saved.cursor,\n seenComments: new Set(saved.seenComments),\n seenIssues: new Set(saved.seenIssues),\n seenReviewComments: new Set(saved.seenReviewComments ?? []),\n }\n : {\n baseline: now,\n cursor: now,\n seenComments: new Set(),\n seenIssues: new Set(),\n seenReviewComments: new Set(),\n },\n );\n }\n this.persistSyncState();\n if (this.stopping) return;\n\n this.stopped = false;\n this.pollIntervalTimer = setInterval(() => {\n void this.poll();\n }, this.config.pollIntervalMs);\n this.pollIntervalTimer.unref();\n\n log.logConnected(\"GitHub\");\n log.logInfo(\n `GitHub bot started as @${this.appSlug}[bot], polling ${this.watchedRepos.length} repo(s) every ${Math.round(this.config.pollIntervalMs / 1000)}s`,\n );\n }\n\n async stop(): Promise<void> {\n this.stopping = true;\n this.pollPending = false;\n if (this.pollIntervalTimer) clearInterval(this.pollIntervalTimer);\n if (this.requestPollTimer) clearTimeout(this.requestPollTimer);\n this.pollIntervalTimer = null;\n this.requestPollTimer = null;\n try {\n if (this.activePoll) await this.activePoll;\n } finally {\n this.stopped = true;\n await Promise.all([...this.queues.values()].map((queue) => queue.close()));\n }\n }\n\n async postMessage(channel: string, text: string): Promise<string> {\n const ref = parseGithubConversationId(channel);\n const parts = splitText(text, GITHUB_MAX_COMMENT_LENGTH, formatGithubContinuation);\n const firstId = await this.postComment(ref, parts[0] ?? text);\n for (const part of parts.slice(1)) {\n await this.postComment(ref, part);\n }\n return String(firstId);\n }\n\n async updateMessage(channel: string, ts: string, text: string): Promise<void> {\n const ref = parseGithubConversationId(channel);\n await githubRetry(() => this.client.updateIssueComment(ref.owner, ref.repo, Number(ts), text));\n }\n\n async addReaction(channel: string, messageTs: string, emoji: string): Promise<void> {\n const ref = parseGithubConversationId(channel);\n const content = GITHUB_REACTIONS[emoji.replace(/^:|:$/g, \"\")];\n if (!content) {\n throw new Error(\n `GitHub does not support reaction '${emoji}' (supported: ${Object.keys(GITHUB_REACTIONS).join(\", \")})`,\n );\n }\n const reviewCommentId = parseReviewCommentTs(messageTs);\n await githubRetry(() => {\n if (messageTs === GITHUB_ISSUE_BODY_TS) {\n return this.client.createIssueReaction(ref.owner, ref.repo, ref.number, content);\n }\n if (reviewCommentId !== null) {\n return this.client.createReviewCommentReaction(\n ref.owner,\n ref.repo,\n reviewCommentId,\n content,\n );\n }\n return this.client.createCommentReaction(ref.owner, ref.repo, Number(messageTs), content);\n });\n }\n\n enqueueEvent(event: ConversationEvent): boolean {\n if (this.stopped) return false;\n const conversationId = event.address.conversationId;\n const queue = this.getQueue(conversationId);\n if (queue.size() >= 5) {\n log.logWarning(\n `Event queue full for ${conversationId}, discarding: ${event.text.substring(0, 50)}`,\n );\n return false;\n }\n log.logInfo(`Enqueueing event for ${conversationId}: ${event.text.substring(0, 50)}`);\n return queue.enqueue(() => {\n const context = createGithubAdapters(event as GithubEvent, this);\n return this.handler.handleEvent(event, this, context);\n });\n }\n\n getMessagingInfo(): MessagingInfo {\n return {\n name: \"github\",\n trustModel: \"open-trigger\",\n formattingGuide:\n \"## GitHub Formatting (GitHub Flavored Markdown)\\n\" +\n \"Standard Markdown plus tables, task lists, fenced code blocks, and ```suggestion blocks.\\n\" +\n \"Reference issues/PRs as #123 and users as @login (mentions notify people — use sparingly).\",\n channels: [],\n users: [],\n };\n }\n\n async postComment(ref: GithubConversationRef, text: string): Promise<number> {\n const comment = await githubRetry(() =>\n this.client.createIssueComment(ref.owner, ref.repo, ref.number, text),\n );\n return comment.id;\n }\n\n async deleteComment(ref: GithubConversationRef, commentId: number): Promise<void> {\n await githubRetry(() => this.client.deleteIssueComment(ref.owner, ref.repo, commentId));\n }\n\n logToFile(conversationId: string, entry: object): void {\n appendChannelLog(this.office(conversationId), entry);\n }\n\n logBotResponse(conversationId: string, text: string, ts: string): void {\n appendBotResponseLog(this.office(conversationId), text, ts);\n }\n\n private getQueue(conversationId: string): MessagingEventQueue {\n let queue = this.queues.get(conversationId);\n if (!queue) {\n queue = new MessagingEventQueue(\"GitHub\");\n this.queues.set(conversationId, queue);\n }\n return queue;\n }\n\n requestPoll(debounceMs = REQUEST_POLL_DEBOUNCE_MS): void {\n if (this.stopped || this.stopping) return;\n if (this.activePoll) {\n this.pollPending = true;\n return;\n }\n if (this.requestPollTimer) return;\n this.requestPollTimer = setTimeout(() => {\n this.requestPollTimer = null;\n void this.poll();\n }, debounceMs);\n this.requestPollTimer.unref();\n }\n\n async poll(): Promise<void> {\n if (this.stopped || this.stopping) return;\n if (this.activePoll) {\n this.pollPending = true;\n return;\n }\n const activePoll = this.pollWatchedRepos();\n this.activePoll = activePoll;\n try {\n await activePoll;\n } finally {\n this.activePoll = null;\n if (this.pollPending) {\n this.pollPending = false;\n this.requestPoll();\n }\n }\n }\n\n private async pollWatchedRepos(): Promise<void> {\n let changed = false;\n for (const repo of this.watchedRepos) {\n try {\n changed = (await this.pollRepo(repo)) || changed;\n } catch (err) {\n log.logWarning(`GitHub poll failed for ${repo.owner}/${repo.repo}`, errorMessage(err));\n }\n }\n if (changed) this.persistSyncState();\n }\n\n private async pollRepo(repo: GithubRepoRef): Promise<boolean> {\n const repoKey = `${repo.owner}/${repo.repo}`;\n const state = this.repoState.get(repoKey);\n if (!state) return false;\n const since = new Date(Date.parse(state.cursor) - POLL_OVERLAP_MS).toISOString();\n let changed = false;\n\n const issues = (await this.client.listIssuesSince(repo.owner, repo.repo, since)) ?? [];\n changed =\n (await this.advanceFeed(state, state.seenIssues, issues, (issue) => ({\n ref: { ...repo, number: issue.number },\n ts: GITHUB_ISSUE_BODY_TS,\n user: issue.user.login,\n text: `# ${issue.title}\\n\\n${issue.body ?? \"\"}`.trim(),\n createdAt: issue.created_at,\n isPr: Boolean(issue.pull_request),\n }))) || changed;\n\n const comments = (await this.client.listIssueCommentsSince(repo.owner, repo.repo, since)) ?? [];\n changed =\n (await this.advanceFeed(state, state.seenComments, comments, (comment) => ({\n ref: { ...repo, number: issueNumberFromUrl(comment.issue_url) },\n ts: String(comment.id),\n user: comment.user.login,\n text: comment.body,\n createdAt: comment.created_at,\n }))) || changed;\n\n const reviewComments =\n (await this.client.listPullReviewCommentsSince(repo.owner, repo.repo, since)) ?? [];\n changed =\n (await this.advanceFeed(state, state.seenReviewComments, reviewComments, (comment) => ({\n ref: { ...repo, number: prNumberFromUrl(comment.pull_request_url) },\n ts: githubReviewCommentTs(comment.id),\n user: comment.user.login,\n text: comment.body,\n createdAt: comment.created_at,\n isPr: true,\n review: {\n commentId: comment.id,\n path: comment.path,\n line: comment.line,\n diffHunk: comment.diff_hunk,\n inReplyToId: comment.in_reply_to_id,\n },\n }))) || changed;\n\n pruneSeen(state.seenComments);\n pruneSeen(state.seenIssues);\n pruneSeen(state.seenReviewComments);\n return changed;\n }\n\n private async advanceFeed<\n T extends {\n id: number;\n created_at: string;\n updated_at: string;\n user: { login: string; type: string };\n },\n >(\n state: RepoWatermark,\n seen: Set<number>,\n items: T[],\n toIncoming: (item: T) => IncomingItem,\n ): Promise<boolean> {\n let changed = false;\n for (const item of items) {\n if (item.updated_at > state.cursor) {\n state.cursor = item.updated_at;\n changed = true;\n }\n if (item.created_at < state.baseline || seen.has(item.id)) continue;\n seen.add(item.id);\n changed = true;\n if (item.user.type === \"Bot\") continue;\n await this.handleIncoming(toIncoming(item));\n }\n return changed;\n }\n\n private loadSyncState(): GithubSyncState | undefined {\n try {\n return readJsonSchemaFileIfExists(\n this.config.syncStatePath,\n SyncStateSchema,\n (detail) => `Malformed GitHub sync state at ${this.config.syncStatePath}: ${detail}`,\n );\n } catch (err) {\n log.logWarning(\"GitHub: ignoring unreadable sync state\", errorMessage(err));\n return undefined;\n }\n }\n\n syncStateSnapshot(): GithubSyncState {\n const state: GithubSyncState = { repos: {} };\n for (const [repoKey, watermark] of this.repoState) {\n state.repos[repoKey] = {\n baseline: watermark.baseline,\n cursor: watermark.cursor,\n seenComments: [...watermark.seenComments],\n seenIssues: [...watermark.seenIssues],\n seenReviewComments: [...watermark.seenReviewComments],\n };\n }\n return state;\n }\n\n private persistSyncState(): void {\n ensureDirExists(dirname(this.config.syncStatePath));\n atomicWritePrivateFile(this.config.syncStatePath, JSON.stringify(this.syncStateSnapshot()));\n }\n\n private mentionPattern(): RegExp | null {\n return this.appSlug ? new RegExp(`@${this.appSlug}(?![\\\\w-])`, \"gi\") : null;\n }\n\n private isMentioned(text: string): boolean {\n const pattern = this.mentionPattern();\n return pattern ? pattern.test(text) : false;\n }\n\n private stripMention(text: string): string {\n const pattern = this.mentionPattern();\n return (pattern ? text.replace(pattern, \"\") : text).trim();\n }\n\n private office(conversationId: string): Office {\n return this.config.workspace.office(createOfficeAddress(\"github\", conversationId));\n }\n\n private isParticipating(conversationId: string): boolean {\n return existsSync(this.office(conversationId).logPath);\n }\n\n private async hasTriggerPermission(ref: GithubConversationRef, user: string): Promise<boolean> {\n const cacheKey = `${ref.owner}/${ref.repo}#${user}`;\n const cached = this.permissionCache.get(cacheKey);\n if (cached && Date.now() < cached.expiresAt) {\n return cached.rank >= REQUIRED_TRIGGER_RANK;\n }\n let rank: number;\n try {\n const role = await githubRetry(() =>\n this.client.getCollaboratorPermission(ref.owner, ref.repo, user),\n );\n rank = Math.max(rankOfPermission(role.role_name ?? \"\"), rankOfPermission(role.permission));\n } catch (err) {\n log.logWarning(\n `GitHub: permission lookup failed for ${user} on ${ref.owner}/${ref.repo}; denying trigger`,\n errorMessage(err),\n );\n return false;\n }\n this.permissionCache.set(cacheKey, {\n rank,\n expiresAt: Date.now() + PERMISSION_CACHE_TTL_MS,\n });\n return rank >= REQUIRED_TRIGGER_RANK;\n }\n\n private async handleIncoming(item: IncomingItem): Promise<void> {\n const conversationId = buildGithubConversationId(item.ref);\n const mentioned = this.isMentioned(item.text);\n const participating = this.isParticipating(conversationId);\n if (!mentioned && !participating) return;\n\n if (!(await this.hasTriggerPermission(item.ref, item.user))) {\n log.logInfo(\n `GitHub: ignoring ${conversationId} comment from ${item.user} (below write permission)`,\n );\n return;\n }\n\n const cleanedText = this.stripMention(item.text);\n const sessionKey = resolveChatSessionKey({\n conversationId,\n conversationKind: \"shared\",\n messageId: item.ts,\n persistentTopLevel: true,\n });\n\n const messageText = item.review\n ? await this.formatReviewMessage(item.ref, item.review, cleanedText)\n : cleanedText;\n\n const eventBase = createConversationEvent({\n platform: \"github\",\n type: item.ts === GITHUB_ISSUE_BODY_TS ? \"issue\" : \"message\",\n conversationId,\n conversationKind: \"shared\",\n ts: item.ts,\n sessionKey,\n user: item.user,\n userName: item.user,\n text: messageText,\n }) as GithubEvent;\n\n await processMessageIntake({\n eventBase,\n addressed: true,\n magicWord: { text: cleanedText, addressed: mentioned, scopeFallback: \"never\" },\n busyPolicy: \"queue\",\n logEntryBase: {\n date: item.createdAt,\n ts: item.ts,\n user: item.user,\n userName: item.user,\n text: messageText,\n isMessagingBot: false,\n },\n log: (entry) => {\n if (!participating && matchMagicWord(cleanedText) === \"stop\") return;\n this.logToFile(conversationId, entry);\n },\n processAttachments: async () => {\n await this.prepareConversation(item, conversationId, participating);\n return [];\n },\n queueKey: conversationId,\n enqueue: (queueKey, work) => this.getQueue(queueKey).enqueue(work),\n handler: this.handler,\n bot: this,\n createContext: (event) => createGithubAdapters(event, this),\n });\n }\n\n private async prepareConversation(\n item: IncomingItem,\n conversationId: string,\n participating: boolean,\n ): Promise<void> {\n let isPrHint = item.isPr;\n if (!participating && item.ts !== GITHUB_ISSUE_BODY_TS) {\n const issue = await this.logIssueContext(item.ref, conversationId, item.createdAt);\n if (issue && isPrHint === undefined) isPrHint = Boolean(issue.pull_request);\n }\n if (!existsSync(conversationRepoDir(this.office(conversationId)))) {\n const isPr = isPrHint ?? (await fetchIsPr(this.client, item.ref));\n await this.ensureRepoClone(item.ref, conversationId, isPr);\n }\n }\n\n private async formatReviewMessage(\n ref: IncomingItem[\"ref\"],\n review: NonNullable<IncomingItem[\"review\"]>,\n cleanedText: string,\n ): Promise<string> {\n const location = review.line !== null ? `${review.path}:${review.line}` : review.path;\n const parts = [`[PR review comment ${githubReviewCommentTs(review.commentId)} on ${location}]`];\n if (review.diffHunk) {\n const hunk =\n review.diffHunk.length > MAX_DIFF_HUNK_CHARS\n ? `…${review.diffHunk.slice(-MAX_DIFF_HUNK_CHARS)}`\n : review.diffHunk;\n parts.push(`\\`\\`\\`diff\\n${hunk}\\n\\`\\`\\``);\n }\n if (review.inReplyToId !== undefined) {\n const turns = await this.reviewThreadContext(ref, review.inReplyToId, review.commentId);\n if (turns.length > 0) {\n parts.push(`Thread so far:\\n${turns.join(\"\\n\")}`);\n }\n }\n parts.push(cleanedText);\n return parts.join(\"\\n\");\n }\n\n private async reviewThreadContext(\n ref: GithubConversationRef,\n rootId: number,\n beforeId: number,\n ): Promise<string[]> {\n try {\n const all = await githubRetry(() =>\n this.client.listPullReviewComments(ref.owner, ref.repo, ref.number),\n );\n return all\n .filter(\n (comment) =>\n (comment.id === rootId || comment.in_reply_to_id === rootId) && comment.id < beforeId,\n )\n .slice(-MAX_THREAD_TURNS)\n .map((comment) => {\n const body =\n comment.body.length > MAX_THREAD_TURN_CHARS\n ? `${comment.body.slice(0, MAX_THREAD_TURN_CHARS)}…`\n : comment.body;\n return `@${comment.user.login}: ${body}`;\n });\n } catch (err) {\n log.logWarning(\n `GitHub: could not fetch review thread context for ${ref.owner}/${ref.repo}#${ref.number}`,\n errorMessage(err),\n );\n return [];\n }\n }\n\n private async logIssueContext(\n ref: GithubConversationRef,\n conversationId: string,\n triggerCreatedAt: string,\n ): Promise<GithubIssue | null> {\n let issue: GithubIssue;\n try {\n issue = await githubRetry(() => this.client.getIssue(ref.owner, ref.repo, ref.number));\n } catch (err) {\n log.logWarning(\n `GitHub: could not fetch issue context for ${conversationId}`,\n errorMessage(err),\n );\n return null;\n }\n const triggerMs = Date.parse(triggerCreatedAt);\n const contextDate = new Date((Number.isFinite(triggerMs) ? triggerMs : Date.now()) - 1000);\n this.logToFile(conversationId, {\n date: contextDate.toISOString(),\n ts: GITHUB_ISSUE_BODY_TS,\n user: issue.user.login,\n userName: issue.user.login,\n text: `# ${issue.title}\\n\\n${issue.body ?? \"\"}`.trim(),\n attachments: [],\n isMessagingBot: false,\n });\n return issue;\n }\n\n private async ensureRepoClone(\n ref: GithubConversationRef,\n conversationId: string,\n isPr: boolean,\n ): Promise<void> {\n const office = this.office(conversationId);\n const dir = conversationRepoDir(office);\n if (existsSync(dir)) return;\n try {\n office.ensure();\n const token = await this.client.createScopedInstallationToken(ref.repo, {\n contents: \"read\",\n });\n const prHeadBranch = isPr ? await fetchPrHeadBranch(this.client, ref) : undefined;\n await cloneRepo({\n url: `https://github.com/${ref.owner}/${ref.repo}.git`,\n dir,\n token,\n botLogin: `${this.appSlug}[bot]`,\n botEmail: this.botEmail ?? `${this.appSlug}[bot]@users.noreply.github.com`,\n prNumber: isPr ? ref.number : undefined,\n prHeadBranch,\n });\n log.logInfo(\n `[${conversationId}] Cloned ${ref.owner}/${ref.repo}${isPr ? ` and checked out PR #${ref.number} head as ${prHeadBranch ?? `pr-${ref.number}`}` : \"\"}`,\n );\n } catch (err) {\n log.logWarning(`GitHub: repo clone failed for ${conversationId}`, errorMessage(err));\n }\n }\n}\n"]}
@@ -17,8 +17,12 @@ export declare class GithubClient {
17
17
  constructor(options: GithubClientOptions);
18
18
  private appJwt;
19
19
  private getInstallationToken;
20
+ private send;
21
+ private readBody;
20
22
  private rawRequest;
23
+ private rawRequestBody;
21
24
  private request;
25
+ private requestBody;
22
26
  getAppSlug(): Promise<string>;
23
27
  getUserId(login: string): Promise<number>;
24
28
  createScopedInstallationToken(repoName: string, permissions: GithubTokenPermissions): Promise<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/adapters/github/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/adapters/github/client.ts"],"names":[],"mappings":"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"}
@@ -40,11 +40,11 @@ export class GithubClient {
40
40
  if (cached && Date.now() < cached.expiresAt - TOKEN_REFRESH_MARGIN_MS) {
41
41
  return cached.value;
42
42
  }
43
- const data = await this.rawRequest("POST", `/app/installations/${this.installationId}/access_tokens`, { auth: `Bearer ${this.appJwt()}` });
43
+ const data = await this.rawRequestBody("POST", `/app/installations/${this.installationId}/access_tokens`, { auth: `Bearer ${this.appJwt()}` });
44
44
  this.installationToken = { value: data.token, expiresAt: Date.parse(data.expires_at) };
45
45
  return this.installationToken.value;
46
46
  }
47
- async rawRequest(method, path, options) {
47
+ async send(method, path, options) {
48
48
  const headers = {
49
49
  Accept: "application/vnd.github+json",
50
50
  "X-GitHub-Api-Version": "2022-11-28",
@@ -62,7 +62,7 @@ export class GithubClient {
62
62
  body: options.body !== undefined ? JSON.stringify(options.body) : undefined,
63
63
  });
64
64
  if (response.status === 304 && !options.responseText) {
65
- return null;
65
+ return response;
66
66
  }
67
67
  if (!response.ok) {
68
68
  const detail = (await response.text().catch(() => "")).slice(0, 300);
@@ -73,39 +73,57 @@ export class GithubClient {
73
73
  if (etag)
74
74
  this.etags.set(path, etag);
75
75
  }
76
- if (response.status === 204 && !options.responseText) {
76
+ return response;
77
+ }
78
+ async readBody(response, responseText) {
79
+ if (!responseText && (response.status === 204 || response.status === 304)) {
77
80
  return null;
78
81
  }
79
- return (await (options.responseText ? response.text() : response.json()));
82
+ return (await (responseText ? response.text() : response.json()));
83
+ }
84
+ async rawRequest(method, path, options) {
85
+ return this.readBody(await this.send(method, path, options), options.responseText);
86
+ }
87
+ async rawRequestBody(method, path, options) {
88
+ const response = await this.send(method, path, options);
89
+ const body = await this.readBody(response, options.responseText);
90
+ if (body === null) {
91
+ throw new Error(`GitHub ${method} ${path} returned no body (${response.status})`);
92
+ }
93
+ return body;
80
94
  }
81
95
  async request(method, path, options = {}) {
82
96
  const token = await this.getInstallationToken();
83
97
  return this.rawRequest(method, path, { ...options, auth: `Bearer ${token}` });
84
98
  }
99
+ async requestBody(method, path, options = {}) {
100
+ const token = await this.getInstallationToken();
101
+ return this.rawRequestBody(method, path, { ...options, auth: `Bearer ${token}` });
102
+ }
85
103
  async getAppSlug() {
86
- const app = await this.rawRequest("GET", "/app", {
104
+ const app = await this.rawRequestBody("GET", "/app", {
87
105
  auth: `Bearer ${this.appJwt()}`,
88
106
  });
89
107
  return app.slug;
90
108
  }
91
109
  async getUserId(login) {
92
- const user = await this.request("GET", `/users/${encodeURIComponent(login)}`);
110
+ const user = await this.requestBody("GET", `/users/${encodeURIComponent(login)}`);
93
111
  return user.id;
94
112
  }
95
113
  async createScopedInstallationToken(repoName, permissions) {
96
- const data = await this.rawRequest("POST", `/app/installations/${this.installationId}/access_tokens`, {
114
+ const data = await this.rawRequestBody("POST", `/app/installations/${this.installationId}/access_tokens`, {
97
115
  auth: `Bearer ${this.appJwt()}`,
98
116
  body: { repositories: [repoName], permissions },
99
117
  });
100
118
  return data.token;
101
119
  }
102
120
  async getRepository(owner, repo) {
103
- const details = await this.request("GET", `/repos/${owner}/${repo}`);
121
+ const details = await this.requestBody("GET", `/repos/${owner}/${repo}`);
104
122
  return details;
105
123
  }
106
124
  async getCollaboratorPermission(owner, repo, username) {
107
125
  try {
108
- const data = await this.request("GET", `/repos/${owner}/${repo}/collaborators/${encodeURIComponent(username)}/permission`);
126
+ const data = await this.requestBody("GET", `/repos/${owner}/${repo}/collaborators/${encodeURIComponent(username)}/permission`);
109
127
  return data;
110
128
  }
111
129
  catch (err) {
@@ -116,25 +134,25 @@ export class GithubClient {
116
134
  }
117
135
  }
118
136
  async createPullRequest(owner, repo, params) {
119
- const pr = await this.request("POST", `/repos/${owner}/${repo}/pulls`, {
137
+ const pr = await this.requestBody("POST", `/repos/${owner}/${repo}/pulls`, {
120
138
  body: params,
121
139
  });
122
140
  return pr;
123
141
  }
124
142
  async getPullRequest(owner, repo, number) {
125
- const pr = await this.request("GET", `/repos/${owner}/${repo}/pulls/${number}`);
143
+ const pr = await this.requestBody("GET", `/repos/${owner}/${repo}/pulls/${number}`);
126
144
  return pr;
127
145
  }
128
146
  async listPullRequestFiles(owner, repo, number) {
129
- const files = await this.request("GET", `/repos/${owner}/${repo}/pulls/${number}/files?per_page=100`);
147
+ const files = await this.requestBody("GET", `/repos/${owner}/${repo}/pulls/${number}/files?per_page=100`);
130
148
  return files;
131
149
  }
132
150
  async listPullRequestReviews(owner, repo, number) {
133
- const reviews = await this.request("GET", `/repos/${owner}/${repo}/pulls/${number}/reviews?per_page=100`);
151
+ const reviews = await this.requestBody("GET", `/repos/${owner}/${repo}/pulls/${number}/reviews?per_page=100`);
134
152
  return reviews;
135
153
  }
136
154
  async listIssueComments(owner, repo, number) {
137
- const comments = await this.request("GET", `/repos/${owner}/${repo}/issues/${number}/comments?per_page=30`);
155
+ const comments = await this.requestBody("GET", `/repos/${owner}/${repo}/issues/${number}/comments?per_page=30`);
138
156
  return comments;
139
157
  }
140
158
  async listIssues(owner, repo, filters = {}) {
@@ -148,7 +166,7 @@ export class GithubClient {
148
166
  params.set("labels", filters.labels);
149
167
  if (filters.creator)
150
168
  params.set("creator", filters.creator);
151
- const issues = await this.request("GET", `/repos/${owner}/${repo}/issues?${params}`);
169
+ const issues = await this.requestBody("GET", `/repos/${owner}/${repo}/issues?${params}`);
152
170
  return issues;
153
171
  }
154
172
  async findOpenPullRequestByBranch(owner, repo, branch) {
@@ -156,15 +174,15 @@ export class GithubClient {
156
174
  return prs?.[0] ?? null;
157
175
  }
158
176
  async listCheckRuns(owner, repo, ref) {
159
- const data = await this.request("GET", `/repos/${owner}/${repo}/commits/${encodeURIComponent(ref)}/check-runs?per_page=50`);
177
+ const data = await this.requestBody("GET", `/repos/${owner}/${repo}/commits/${encodeURIComponent(ref)}/check-runs?per_page=50`);
160
178
  return data.check_runs;
161
179
  }
162
180
  async getJobLog(owner, repo, jobId) {
163
- const text = await this.request("GET", `/repos/${owner}/${repo}/actions/jobs/${jobId}/logs`, { responseText: true });
181
+ const text = await this.requestBody("GET", `/repos/${owner}/${repo}/actions/jobs/${jobId}/logs`, { responseText: true });
164
182
  return text;
165
183
  }
166
184
  async listInstallationRepositories() {
167
- const data = await this.request("GET", "/installation/repositories?per_page=100");
185
+ const data = await this.requestBody("GET", "/installation/repositories?per_page=100");
168
186
  return data.repositories;
169
187
  }
170
188
  async listIssueCommentsSince(owner, repo, since) {
@@ -174,14 +192,14 @@ export class GithubClient {
174
192
  return this.request("GET", `/repos/${owner}/${repo}/pulls/comments?sort=updated&direction=asc&since=${encodeURIComponent(since)}&per_page=100`, { conditional: true });
175
193
  }
176
194
  async listPullReviewComments(owner, repo, number) {
177
- const comments = await this.request("GET", `/repos/${owner}/${repo}/pulls/${number}/comments?per_page=100`);
195
+ const comments = await this.requestBody("GET", `/repos/${owner}/${repo}/pulls/${number}/comments?per_page=100`);
178
196
  return comments;
179
197
  }
180
198
  async listIssuesSince(owner, repo, since) {
181
199
  return this.request("GET", `/repos/${owner}/${repo}/issues?state=all&sort=updated&direction=asc&since=${encodeURIComponent(since)}&per_page=100`, { conditional: true });
182
200
  }
183
201
  async getIssue(owner, repo, number) {
184
- const issue = await this.request("GET", `/repos/${owner}/${repo}/issues/${number}`);
202
+ const issue = await this.requestBody("GET", `/repos/${owner}/${repo}/issues/${number}`);
185
203
  return issue;
186
204
  }
187
205
  async addIssueLabels(owner, repo, number, labels) {
@@ -208,7 +226,7 @@ export class GithubClient {
208
226
  });
209
227
  }
210
228
  async createIssueComment(owner, repo, number, body) {
211
- const comment = await this.request("POST", `/repos/${owner}/${repo}/issues/${number}/comments`, { body: { body } });
229
+ const comment = await this.requestBody("POST", `/repos/${owner}/${repo}/issues/${number}/comments`, { body: { body } });
212
230
  return comment;
213
231
  }
214
232
  async updateIssueComment(owner, repo, commentId, body) {
@@ -225,7 +243,7 @@ export class GithubClient {
225
243
  });
226
244
  }
227
245
  async replyToReviewComment(owner, repo, number, commentId, body) {
228
- const comment = await this.request("POST", `/repos/${owner}/${repo}/pulls/${number}/comments/${commentId}/replies`, { body: { body } });
246
+ const comment = await this.requestBody("POST", `/repos/${owner}/${repo}/pulls/${number}/comments/${commentId}/replies`, { body: { body } });
229
247
  return comment;
230
248
  }
231
249
  async createReviewCommentReaction(owner, repo, commentId, content) {