Files
PaperClipAI/server/src/__tests__/helpers/github-skills.ts
T
DottaandPaperclip 473c80d13f Automatically import and update project repository skills (#16066)
Automatically import skills from new GitHub project repositories and update enabled sources in the background. Preserve project-derived access, saved selections, immutable execution versions and explicit pins; add legacy adoption, refresh and connection repair in Sources.

Include durable scheduling and bounded work credits, production Storybook journeys, real GitHub-to-routine acceptance receipts and final-head CI/security/Greptile qualification.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-13 16:11:43 -05:00

18 lines
1.3 KiB
TypeScript

import { createHash } from "node:crypto";
import type { GitHubRead } from "../../services/github-skill-source.js";
export function githubFixture(files: Record<string, string | Buffer>, modes: Record<string, string> = {}, commit = "a".repeat(40)): GitHubRead {
const entries = Object.keys(files).map((path, i) => ({ path, type: modes[path] === '160000' ? 'commit' : 'blob', mode: modes[path] ?? '100644', sha: String(i), size: Buffer.byteLength(files[path]!) }));
const treeSha = createHash("sha1").update(JSON.stringify(entries.map(entry => [entry.path, entry.mode, files[entry.path]]).sort())).digest("hex");
const read = (async (url: string) => {
if (url === '/repos/acme/skills') return { id: 42, full_name: 'acme/skills', default_branch: 'main' };
if (url.startsWith('/repos/acme/skills/commits/')) return { sha: commit, commit: { tree: { sha: treeSha } } };
throw new Error(`Unexpected request ${url}`);
}) as GitHubRead;
read.openSnapshot = async (_input, options) => {
options?.signal?.throwIfAborted();
await options?.onDownload?.({ stage: 'receiving', percent: 50, receivedBytes: 1024 });
return { commitSha: commit, treeSha, downloadBytes: entries.reduce((sum, entry) => sum + (entry.size ?? 0), 0), entries, readBlob: async entry => Buffer.from(files[entry.path]!), release: async () => {} };
};
return read;
}