feat(ext/sw): GitHost.lastCommit() for vault-presence metadata
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,12 +14,14 @@ import { uint8ArrayToBase64, base64ToUint8Array, BLOB_THRESHOLD_BYTES } from './
|
||||
export class GitHubHost implements GitHost {
|
||||
private baseUrl: string;
|
||||
private gitApiBase: string;
|
||||
private commitsUrl: string;
|
||||
private branch: string = 'main';
|
||||
private headers: Record<string, string>;
|
||||
|
||||
constructor(repoPath: string, apiToken: string) {
|
||||
this.baseUrl = `https://api.github.com/repos/${repoPath}/contents`;
|
||||
this.gitApiBase = `https://api.github.com/repos/${repoPath}/git`;
|
||||
this.commitsUrl = `https://api.github.com/repos/${repoPath}/commits`;
|
||||
this.headers = {
|
||||
'Authorization': `Bearer ${apiToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
@@ -109,6 +111,24 @@ export class GitHubHost implements GitHost {
|
||||
return json.map((item: { name: string }) => item.name);
|
||||
}
|
||||
|
||||
async lastCommit(path: string): Promise<{ sha: string; author: string; date: string } | null> {
|
||||
try {
|
||||
const url = `${this.commitsUrl}?path=${encodeURIComponent(path)}&per_page=1`;
|
||||
const resp = await fetch(url, { headers: this.headers });
|
||||
if (!resp.ok) return null;
|
||||
const json = await resp.json();
|
||||
if (!Array.isArray(json) || json.length === 0) return null;
|
||||
const c = json[0];
|
||||
return {
|
||||
sha: String(c.sha).slice(0, 7),
|
||||
author: c.commit?.author?.name ?? 'unknown',
|
||||
date: c.commit?.author?.date ?? '',
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async putBlob(path: string, content: Uint8Array, message: string): Promise<string> {
|
||||
if (content.length <= BLOB_THRESHOLD_BYTES) {
|
||||
// Contents API path — same as writeFile
|
||||
|
||||
Reference in New Issue
Block a user