@inkeep/agents-work-apps 0.0.0-dev-20260222144437 → 0.0.0-dev-20260223164732

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.
@@ -1,7 +1,7 @@
1
- import * as hono0 from "hono";
1
+ import * as hono1 from "hono";
2
2
 
3
3
  //#region src/github/mcp/auth.d.ts
4
- declare const githubMcpAuth: () => hono0.MiddlewareHandler<{
4
+ declare const githubMcpAuth: () => hono1.MiddlewareHandler<{
5
5
  Variables: {
6
6
  toolId: string;
7
7
  };
@@ -1,11 +1,11 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types5 from "hono/types";
2
+ import * as hono_types3 from "hono/types";
3
3
 
4
4
  //#region src/github/mcp/index.d.ts
5
5
  declare const app: Hono<{
6
6
  Variables: {
7
7
  toolId: string;
8
8
  };
9
- }, hono_types5.BlankSchema, "/">;
9
+ }, hono_types3.BlankSchema, "/">;
10
10
  //#endregion
11
11
  export { app as default };
@@ -1,7 +1,7 @@
1
1
  import runDbClient_default from "../../db/runDbClient.js";
2
2
  import { githubMcpAuth } from "./auth.js";
3
3
  import { ReactionContentSchema } from "./schemas.js";
4
- import { commitFileChanges, commitNewFile, createIssueCommentReaction, createPullRequestReviewCommentReaction, deleteIssueCommentReaction, deletePullRequestReviewCommentReaction, fetchComments, fetchPrFileDiffs, fetchPrFiles, fetchPrInfo, formatFileDiff, generatePrMarkdown, getGitHubClientFromRepo, listIssueCommentReactions, listPullRequestReviewCommentReactions, visualizeUpdateOperations } from "./utils.js";
4
+ import { commitFileChanges, commitNewFile, createIssueCommentReaction, createPullRequestReviewCommentReaction, deleteIssueCommentReaction, deletePullRequestReviewCommentReaction, fetchBranchChangedFiles, fetchComments, fetchPrFileDiffs, fetchPrFiles, fetchPrInfo, formatFileDiff, generatePrMarkdown, getGitHubClientFromRepo, listIssueCommentReactions, listPullRequestReviewCommentReactions, visualizeUpdateOperations } from "./utils.js";
5
5
  import { z } from "@hono/zod-openapi";
6
6
  import { getMcpToolRepositoryAccessWithDetails } from "@inkeep/agents-core";
7
7
  import { Hono } from "hono";
@@ -267,6 +267,65 @@ const getServer = async (toolId) => {
267
267
  };
268
268
  }
269
269
  });
270
+ server.tool("get-changed-files-for-branch", `Get the list of files changed on a branch compared to a base ref, without requiring a pull request. Returns file paths, status, additions/deletions, and optionally patches and full file contents. ${getAvailableRepositoryString(repositoryAccess)}`, {
271
+ owner: z.string().describe("Repository owner name"),
272
+ repo: z.string().describe("Repository name"),
273
+ head: z.string().describe("The branch or ref to check for changes (e.g. \"feat/my-feature\")"),
274
+ base: z.string().optional().describe("The base branch or ref to compare against (defaults to the repository default branch)"),
275
+ file_paths: z.array(z.string()).optional().describe("Optional list of file path glob patterns to filter results"),
276
+ include_contents: z.boolean().default(false).describe("Whether to include full file contents for each changed file"),
277
+ include_patch: z.boolean().default(false).describe("Whether to include the patch/diff text for each changed file")
278
+ }, async ({ owner, repo, head, base, file_paths, include_contents, include_patch }) => {
279
+ try {
280
+ let githubClient;
281
+ try {
282
+ githubClient = getGitHubClientFromRepo(owner, repo, installationIdMap);
283
+ } catch (error) {
284
+ return {
285
+ content: [{
286
+ type: "text",
287
+ text: `Error accessing GitHub: ${error instanceof Error ? error.message : "Unknown error"}`
288
+ }],
289
+ isError: true
290
+ };
291
+ }
292
+ const baseRef = base ?? (await githubClient.rest.repos.get({
293
+ owner,
294
+ repo
295
+ })).data.default_branch;
296
+ const files = await fetchBranchChangedFiles(githubClient, owner, repo, baseRef, head, {
297
+ pathFilters: file_paths ?? [],
298
+ includeContents: include_contents,
299
+ includePatch: include_patch
300
+ });
301
+ if (files.length === 0) return { content: [{
302
+ type: "text",
303
+ text: `No changed files found between ${baseRef} and ${head} in ${owner}/${repo}.${file_paths?.length ? `\n\nFilters applied: ${file_paths.join(", ")}` : ""}`
304
+ }] };
305
+ const output = await formatFileDiff(0, files, include_contents);
306
+ return { content: [{
307
+ type: "text",
308
+ text: `## Changed files: ${baseRef}...${head} in ${owner}/${repo}\n\nFound ${files.length} changed file(s).\n\n` + output
309
+ }] };
310
+ } catch (error) {
311
+ if (error instanceof Error && "status" in error) {
312
+ if (error.status === 404) return {
313
+ content: [{
314
+ type: "text",
315
+ text: `Repository ${owner}/${repo} not found, or one of the refs ("${base ?? "default"}", "${head}") does not exist.`
316
+ }],
317
+ isError: true
318
+ };
319
+ }
320
+ return {
321
+ content: [{
322
+ type: "text",
323
+ text: `Error fetching changed files: ${error instanceof Error ? error.message : "Unknown error"}`
324
+ }],
325
+ isError: true
326
+ };
327
+ }
328
+ });
270
329
  server.tool("create-branch", `Create a new branch in a repository. ${getAvailableRepositoryString(repositoryAccess)}`, {
271
330
  owner: z.string().describe("Repository owner name"),
272
331
  repo: z.string().describe("Repository name"),
@@ -76,8 +76,8 @@ declare const ChangedFileSchema: z.ZodObject<{
76
76
  path: z.ZodString;
77
77
  status: z.ZodEnum<{
78
78
  added: "added";
79
- modified: "modified";
80
79
  removed: "removed";
80
+ modified: "modified";
81
81
  renamed: "renamed";
82
82
  copied: "copied";
83
83
  changed: "changed";
@@ -152,6 +152,15 @@ declare function fetchPrFiles(octokit: Octokit, owner: string, repo: string, prN
152
152
  * Get file-based diffs with all commit messages that impacted each file.
153
153
  */
154
154
  declare function fetchPrFileDiffs(octokit: Octokit, owner: string, repo: string, prNumber: number): Promise<ChangedFile[]>;
155
+ /**
156
+ * Fetch files changed on a branch compared to a base ref, without requiring a PR.
157
+ * Uses the GitHub Compare API (`repos.compareCommitsWithBasehead`).
158
+ */
159
+ declare function fetchBranchChangedFiles(octokit: Octokit, owner: string, repo: string, base: string, head: string, options?: {
160
+ pathFilters?: string[];
161
+ includeContents?: boolean;
162
+ includePatch?: boolean;
163
+ }): Promise<ChangedFile[]>;
155
164
  /**
156
165
  * Fetch all PR comments (both issue comments and review comments)
157
166
  */
@@ -247,4 +256,4 @@ declare function listIssueCommentReactions(octokit: Octokit, owner: string, repo
247
256
  declare function listPullRequestReviewCommentReactions(octokit: Octokit, owner: string, repo: string, commentId: number): Promise<ReactionDetail[]>;
248
257
  declare function formatFileDiff(pullRequestNumber: number, files: ChangedFile[], includeContents?: boolean): Promise<string>;
249
258
  //#endregion
250
- export { CommitData, LLMUpdateOperation, PullCommit, ReactionDetail, applyOperation, applyOperations, commitFileChanges, commitNewFile, createIssueCommentReaction, createPullRequestReviewCommentReaction, deleteIssueCommentReaction, deletePullRequestReviewCommentReaction, fetchComments, fetchCommitDetails, fetchPrCommits, fetchPrFileDiffs, fetchPrFiles, fetchPrInfo, formatFileDiff, generatePrMarkdown, getFilePathsInRepo, getGitHubClientFromInstallationId, getGitHubClientFromRepo, listIssueCommentReactions, listPullRequestReviewCommentReactions, validateLineNumbers, visualizeUpdateOperations };
259
+ export { CommitData, LLMUpdateOperation, PullCommit, ReactionDetail, applyOperation, applyOperations, commitFileChanges, commitNewFile, createIssueCommentReaction, createPullRequestReviewCommentReaction, deleteIssueCommentReaction, deletePullRequestReviewCommentReaction, fetchBranchChangedFiles, fetchComments, fetchCommitDetails, fetchPrCommits, fetchPrFileDiffs, fetchPrFiles, fetchPrInfo, formatFileDiff, generatePrMarkdown, getFilePathsInRepo, getGitHubClientFromInstallationId, getGitHubClientFromRepo, listIssueCommentReactions, listPullRequestReviewCommentReactions, validateLineNumbers, visualizeUpdateOperations };
@@ -265,6 +265,92 @@ async function fetchPrFileDiffs(octokit, owner, repo, prNumber) {
265
265
  }
266
266
  }
267
267
  /**
268
+ * Fetch files changed on a branch compared to a base ref, without requiring a PR.
269
+ * Uses the GitHub Compare API (`repos.compareCommitsWithBasehead`).
270
+ */
271
+ async function fetchBranchChangedFiles(octokit, owner, repo, base, head, options = {}) {
272
+ const { pathFilters = [], includeContents = false, includePatch = false } = options;
273
+ logger.info({
274
+ owner,
275
+ repo,
276
+ base,
277
+ head,
278
+ pathFilters,
279
+ includeContents,
280
+ includePatch
281
+ }, `Fetching changed files between ${base}...${head}`);
282
+ const totalCommits = (await octokit.rest.repos.compareCommitsWithBasehead({
283
+ owner,
284
+ repo,
285
+ basehead: `${base}...${head}`,
286
+ per_page: 1
287
+ })).data.total_commits;
288
+ const collectedFiles = [];
289
+ let page = 1;
290
+ const perPage = 100;
291
+ while (true) {
292
+ const files = (await octokit.rest.repos.compareCommitsWithBasehead({
293
+ owner,
294
+ repo,
295
+ basehead: `${base}...${head}`,
296
+ per_page: perPage,
297
+ page
298
+ })).data.files ?? [];
299
+ if (files.length === 0) break;
300
+ for (const file of files) {
301
+ if (pathFilters.length > 0 && !pathFilters.some((filter) => minimatch(file.filename, filter))) continue;
302
+ collectedFiles.push({
303
+ commit_messages: [],
304
+ path: file.filename,
305
+ status: file.status,
306
+ additions: file.additions,
307
+ deletions: file.deletions,
308
+ patch: includePatch ? file.patch : void 0,
309
+ previousPath: file.previous_filename
310
+ });
311
+ }
312
+ if (files.length < perPage) break;
313
+ page++;
314
+ }
315
+ if (includeContents) {
316
+ const BATCH_SIZE = 10;
317
+ const filesToFetch = collectedFiles.filter((f) => f.status !== "removed");
318
+ for (let i = 0; i < filesToFetch.length; i += BATCH_SIZE) {
319
+ const batch = filesToFetch.slice(i, i + BATCH_SIZE);
320
+ await Promise.all(batch.map(async (changedFile) => {
321
+ try {
322
+ const { data: content } = await octokit.rest.repos.getContent({
323
+ owner,
324
+ repo,
325
+ path: changedFile.path,
326
+ ref: head
327
+ });
328
+ if ("content" in content && content.encoding === "base64") changedFile.contents = Buffer.from(content.content, "base64").toString("utf-8");
329
+ } catch (error) {
330
+ logger.warn({
331
+ owner,
332
+ repo,
333
+ base,
334
+ head,
335
+ file: changedFile.path
336
+ }, `Failed to fetch contents for ${changedFile.path}: ${error}`);
337
+ }
338
+ }));
339
+ }
340
+ }
341
+ logger.info({
342
+ owner,
343
+ repo,
344
+ base,
345
+ head,
346
+ totalCommits,
347
+ pathFilters,
348
+ includeContents,
349
+ fileCount: collectedFiles.length
350
+ }, `Found ${collectedFiles.length} changed files between ${base}...${head} (${totalCommits} commits)`);
351
+ return collectedFiles;
352
+ }
353
+ /**
268
354
  * Fetch all PR comments (both issue comments and review comments)
269
355
  */
270
356
  async function fetchComments(octokit, owner, repo, prNumber) {
@@ -694,4 +780,4 @@ async function formatFileDiff(pullRequestNumber, files, includeContents = false)
694
780
  }
695
781
 
696
782
  //#endregion
697
- export { applyOperation, applyOperations, commitFileChanges, commitNewFile, createIssueCommentReaction, createPullRequestReviewCommentReaction, deleteIssueCommentReaction, deletePullRequestReviewCommentReaction, fetchComments, fetchCommitDetails, fetchPrCommits, fetchPrFileDiffs, fetchPrFiles, fetchPrInfo, formatFileDiff, generatePrMarkdown, getFilePathsInRepo, getGitHubClientFromInstallationId, getGitHubClientFromRepo, listIssueCommentReactions, listPullRequestReviewCommentReactions, validateLineNumbers, visualizeUpdateOperations };
783
+ export { applyOperation, applyOperations, commitFileChanges, commitNewFile, createIssueCommentReaction, createPullRequestReviewCommentReaction, deleteIssueCommentReaction, deletePullRequestReviewCommentReaction, fetchBranchChangedFiles, fetchComments, fetchCommitDetails, fetchPrCommits, fetchPrFileDiffs, fetchPrFiles, fetchPrInfo, formatFileDiff, generatePrMarkdown, getFilePathsInRepo, getGitHubClientFromInstallationId, getGitHubClientFromRepo, listIssueCommentReactions, listPullRequestReviewCommentReactions, validateLineNumbers, visualizeUpdateOperations };
@@ -1,7 +1,7 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types3 from "hono/types";
2
+ import * as hono_types6 from "hono/types";
3
3
 
4
4
  //#region src/github/routes/setup.d.ts
5
- declare const app: Hono<hono_types3.BlankEnv, hono_types3.BlankSchema, "/">;
5
+ declare const app: Hono<hono_types6.BlankEnv, hono_types6.BlankSchema, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -1,7 +1,7 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types6 from "hono/types";
2
+ import * as hono_types4 from "hono/types";
3
3
 
4
4
  //#region src/github/routes/tokenExchange.d.ts
5
- declare const app: Hono<hono_types6.BlankEnv, hono_types6.BlankSchema, "/">;
5
+ declare const app: Hono<hono_types4.BlankEnv, hono_types4.BlankSchema, "/">;
6
6
  //#endregion
7
7
  export { app as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-work-apps",
3
- "version": "0.0.0-dev-20260222144437",
3
+ "version": "0.0.0-dev-20260223164732",
4
4
  "description": "First party integrations for Inkeep Agents",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -33,7 +33,7 @@
33
33
  "jose": "^6.1.0",
34
34
  "minimatch": "^10.1.1",
35
35
  "slack-block-builder": "^2.8.0",
36
- "@inkeep/agents-core": "0.0.0-dev-20260222144437"
36
+ "@inkeep/agents-core": "0.0.0-dev-20260223164732"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@hono/zod-openapi": "^1.1.5",