From ffc144fd31cbfc3059bd3a655f08f6111b1fbb25 Mon Sep 17 00:00:00 2001 From: posimai Date: Fri, 24 Apr 2026 07:56:55 +0900 Subject: [PATCH] =?UTF-8?q?feat(chronicle):=20=E8=A8=AD=E5=AE=9A=E3=83=91?= =?UTF-8?q?=E3=83=8D=E3=83=AB=E3=81=AB=20GitHub=20PAT=20=E6=AC=84=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E3=80=81=E3=83=96=E3=83=A9=E3=82=A6=E3=82=B6?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=20GitHub=20API=20=E6=8E=A5=E7=B6=9A=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 98 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 22 deletions(-) diff --git a/index.html b/index.html index 3acc068..a64ed12 100644 --- a/index.html +++ b/index.html @@ -180,7 +180,23 @@
-
外観
+
GitHub 連携
+
+
Personal Access Token
+
+ github.com → Settings → Developer settings
+ → Fine-grained tokens → Generate new token
+ Permissions: Contents: Read-only +
+
+ + +
+
+
+ +
外観
テーマ
@@ -487,47 +503,85 @@ document.getElementById('copyBtn').addEventListener('click', async () => { } }); +// ── GitHub PAT 設定 ─────────────────── +const GH_PAT_KEY = 'posimai-chronicle-gh-pat'; +function getGhPat() { return localStorage.getItem(GH_PAT_KEY) || ''; } + +(function initGhPatUI() { + const input = document.getElementById('ghPatInput'); + const status = document.getElementById('ghPatStatus'); + const pat = getGhPat(); + if (pat) { + input.value = pat; + status.textContent = '設定済み'; + status.style.color = 'var(--accent)'; + } + document.getElementById('ghPatSaveBtn').addEventListener('click', () => { + const val = input.value.trim(); + if (!val) { + localStorage.removeItem(GH_PAT_KEY); + status.textContent = '削除しました'; + status.style.color = 'var(--text3)'; + return; + } + localStorage.setItem(GH_PAT_KEY, val); + status.textContent = '保存しました'; + status.style.color = 'var(--accent)'; + }); +})(); + // ── コミット読み込み ────────────────── document.getElementById('loadCommitsBtn').addEventListener('click', async () => { - const token = getToken(); - if (!token) { showToast('ログインが必要です'); return; } + const ghPat = getGhPat(); + if (!ghPat) { + showToast('設定パネルで GitHub PAT を設定してください'); + document.getElementById('settingsBtn').click(); + return; + } const btn = document.getElementById('loadCommitsBtn'); btn.disabled = true; btn.innerHTML = ' 読み込み中'; + const since = new Date(Date.now() - activeDays * 86400000).toISOString(); + try { - const resp = await fetch(`${API}/chronicle/activity?days=${activeDays}`, { - headers: { 'Authorization': `Bearer ${token}` } - }); + const resp = await fetch( + 'https://api.github.com/orgs/posimai/events?per_page=100', + { headers: { 'Authorization': `Bearer ${ghPat}`, 'Accept': 'application/vnd.github+json' } } + ); + if (resp.status === 401) throw new Error('PAT が無効です。設定を確認してください'); + if (!resp.ok) throw new Error(`GitHub API ${resp.status}`); - if (resp.status === 503) { - showToast('VPS に CHRONICLE_GITHUB_TOKEN が未設定です'); - return; + const events = await resp.json(); + const commits = []; + const byRepo = {}; + + for (const ev of events) { + if (ev.type !== 'PushEvent') continue; + if (ev.created_at < since) continue; + const repo = ev.repo.name.replace('posimai/', ''); + if (!byRepo[repo]) byRepo[repo] = []; + for (const c of ev.payload?.commits || []) { + const msg = c.message.split('\n')[0]; + if (/^Merge\b/i.test(msg)) continue; + byRepo[repo].push(msg); + commits.push(msg); + } } - if (!resp.ok) throw new Error(`HTTP ${resp.status}`); - const data = await resp.json(); - if (!data.commits?.length) { + if (!commits.length) { showToast('この期間にコミットが見つかりませんでした'); return; } - const byRepo = {}; - for (const c of data.commits) { - if (!byRepo[c.repo]) byRepo[c.repo] = []; - byRepo[c.repo].push(c.message); - } - const lines = []; for (const [repo, messages] of Object.entries(byRepo)) { lines.push(`【${repo}】`); for (const m of messages) lines.push(`- ${m}`); } - - const area = document.getElementById('activities'); - area.value = lines.join('\n'); - showToast(`${data.commits.length} 件のコミットを読み込みました`); + document.getElementById('activities').value = lines.join('\n'); + showToast(`${commits.length} 件のコミットを読み込みました`); } catch (e) { showToast(`読み込み失敗: ${e.message}`); } finally {