From ad9cfaa85a209f0689488619e05b27db5debb9db Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 02:05:38 +0000 Subject: [PATCH] chore: publish from main --- .github/plugin/marketplace.json | 6 + .../work-hub/.github/plugin/plugin.json | 19 + extensions/work-hub/README.md | 15 + extensions/work-hub/assets/preview.png | Bin 0 -> 195356 bytes extensions/work-hub/data.mjs | 1060 +++++++++++++++ extensions/work-hub/extension.mjs | 376 ++++++ extensions/work-hub/package.json | 18 + extensions/work-hub/renderer.mjs | 1138 +++++++++++++++++ 8 files changed, 2632 insertions(+) create mode 100644 extensions/work-hub/.github/plugin/plugin.json create mode 100644 extensions/work-hub/README.md create mode 100644 extensions/work-hub/assets/preview.png create mode 100644 extensions/work-hub/data.mjs create mode 100644 extensions/work-hub/extension.mjs create mode 100644 extensions/work-hub/package.json create mode 100644 extensions/work-hub/renderer.mjs diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 6f765330..3472988d 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -1285,6 +1285,12 @@ "repo": "microsoft/win-dev-skills", "path": "plugins/winui" } + }, + { + "name": "work-hub", + "source": "extensions/work-hub", + "description": "Generic cross-repo command center canvas for GitHub Copilot with onboarding, focus planning, repo health, work signals, and session cleanup.", + "version": "1.0.0" } ] } diff --git a/extensions/work-hub/.github/plugin/plugin.json b/extensions/work-hub/.github/plugin/plugin.json new file mode 100644 index 00000000..3e85d376 --- /dev/null +++ b/extensions/work-hub/.github/plugin/plugin.json @@ -0,0 +1,19 @@ +{ + "name": "work-hub", + "description": "Generic cross-repo command center canvas for GitHub Copilot with onboarding, focus planning, repo health, work signals, and session cleanup.", + "version": "1.0.0", + "author": { + "name": "James Montemagno", + "url": "https://github.com/jamesmontemagno" + }, + "keywords": [ + "cross-repo-dashboard", + "focus-planning", + "repo-health", + "session-cleanup", + "work-triage", + "workflow-visibility" + ], + "logo": "assets/preview.png", + "extensions": "." +} diff --git a/extensions/work-hub/README.md b/extensions/work-hub/README.md new file mode 100644 index 00000000..50b84173 --- /dev/null +++ b/extensions/work-hub/README.md @@ -0,0 +1,15 @@ +# Work Hub + +Generic cross-repo command center canvas for GitHub Copilot. + +## What it does + +- First-run onboarding to pick GitHub repositories or local projects +- Focus planning based on mood, available time, bandwidth, and work intent +- Cross-repo work explorer for pull requests, issues, deployments, releases, and active sessions +- Repository health overview with local git and GitHub signals +- Session cleanup flow for stale worktrees and older coding sessions + +## Assets + +- `assets/preview.png` - gallery preview image required by the Awesome Copilot extensions catalog. diff --git a/extensions/work-hub/assets/preview.png b/extensions/work-hub/assets/preview.png new file mode 100644 index 0000000000000000000000000000000000000000..353467c33633065735067fdef35adc70fd663825 GIT binary patch literal 195356 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 z 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 literal 0 HcmV?d00001 diff --git a/extensions/work-hub/data.mjs b/extensions/work-hub/data.mjs new file mode 100644 index 00000000..5a0f2405 --- /dev/null +++ b/extensions/work-hub/data.mjs @@ -0,0 +1,1060 @@ +import { execFile } from "node:child_process"; +import { mkdir, readFile, readdir, writeFile } from "node:fs/promises"; +import { existsSync } from "node:fs"; +import os from "node:os"; +import path from "node:path"; + +export const MOODS = ["focused", "low-energy", "maintenance", "creative", "urgent"]; +export const BUSYNESS = ["busy", "normal", "open"]; +export const MINUTE_OPTIONS = [15, 30, 60, 120]; +export const FOCUS_INTENTS = ["balanced", "prs", "new-code", "issue-triage", "maintenance"]; + +const DEFAULT_PREFERENCES = { mood: "focused", minutes: 30, busyness: "normal", focusIntent: "balanced" }; +const DEFAULT_CONFIG = { repos: [], onboarded: false }; + +const CACHE_TTL_MS = 2 * 60 * 1000; +const COMMAND_TIMEOUT_MS = 18 * 1000; +const PROJECTS_DIR = path.join(os.homedir(), "Projects"); +const LOCAL_PROJECT_DIRS = [ + PROJECTS_DIR, + path.join(os.homedir(), "src"), + path.join(os.homedir(), "source"), + path.join(os.homedir(), "code"), + path.join(os.homedir(), "GitHub"), +]; +const WORKTREES_DIR = path.join(PROJECTS_DIR, "copilot-worktrees"); +const SESSION_STORE_PATH = path.join(os.homedir(), ".copilot", "session-store.db"); +const ARTIFACT_DIR = path.join(os.homedir(), ".copilot", "extensions", "work-hub", "artifacts"); +const PREFERENCES_PATH = path.join(ARTIFACT_DIR, "preferences.json"); +const CONFIG_PATH = path.join(ARTIFACT_DIR, "config.json"); + +let cachedModel = null; +let cachedAt = 0; +let refreshPromise = null; +let discoveryCache = { at: 0, value: null }; + +function nowMs() { + return Date.now(); +} + +export function daysSince(dateLike) { + if (!dateLike) return null; + const time = new Date(dateLike).getTime(); + if (!Number.isFinite(time)) return null; + return Math.max(0, Math.floor((nowMs() - time) / 86400000)); +} + +export function ageLabel(days) { + if (days === null || days === undefined) return "unknown"; + if (days === 0) return "today"; + if (days === 1) return "1 day"; + if (days < 30) return `${days} days`; + const months = Math.floor(days / 30); + if (months < 18) return `${months} mo`; + return `${Math.floor(days / 365)} yr`; +} + +function isHumanLogin(login) { + if (!login) return false; + return !/\[bot\]$/i.test(login) && !/-bot$/i.test(login) && login.toLowerCase() !== "github-actions"; +} + +function normalizeLogin(entity) { + if (!entity) return ""; + if (typeof entity === "string") return entity; + return entity.login || entity.name || entity.slug || ""; +} + +function knownUserLogins(extraLogin) { + return new Set([extraLogin].filter(Boolean).map((value) => value.toLowerCase())); +} + +function ownerOf(slug) { + return String(slug || "").split("/")[0] || ""; +} + +function nameOf(slug) { + return String(slug || "").split("/")[1] || ""; +} + +function ownerEnv(owner) { + const token = process.env[`COPILOT_GH_ACCOUNT_github_2E_com_${owner}`]; + if (owner && token) { + return { GH_HOST: "github.com", GH_TOKEN: token }; + } + return {}; +} + +function parseRepoSlugFromRemote(remote) { + const value = String(remote || "").trim(); + if (!value) return null; + const ssh = /^git@[^:]+:([^/\s]+)\/([^/\s]+?)(?:\.git)?$/i.exec(value); + if (ssh) return `${ssh[1]}/${ssh[2]}`; + try { + const url = new URL(value); + const parts = url.pathname.replace(/^\/+/, "").replace(/\.git$/i, "").split("/"); + if (parts.length >= 2 && parts[0] && parts[1]) return `${parts[0]}/${parts[1]}`; + } catch { + // Not a URL; fall through to owner/repo parsing. + } + const slug = value.replace(/\.git$/i, ""); + return /^[^/\s]+\/[^/\s]+$/.test(slug) ? slug : null; +} + +function guessLocalPath(slug) { + const owner = ownerOf(slug); + const name = nameOf(slug); + const candidates = [ + path.join(PROJECTS_DIR, name), + path.join(PROJECTS_DIR, `${owner}_${name}`), + ]; + for (const candidate of candidates) { + if (existsSync(candidate)) return candidate; + } + return null; +} + +function run(command, args, options = {}) { + return new Promise((resolve) => { + execFile( + command, + args, + { + cwd: options.cwd, + env: { ...process.env, ...(options.env || {}) }, + timeout: options.timeoutMs || COMMAND_TIMEOUT_MS, + maxBuffer: 1024 * 1024 * 8, + }, + (error, stdout, stderr) => { + if (error) { + resolve({ ok: false, stdout: stdout || "", stderr: stderr || "", message: (stderr || error.message || "Command failed").trim(), code: error.code }); + return; + } + resolve({ ok: true, stdout: stdout || "", stderr: stderr || "" }); + }, + ); + }); +} + +async function ghJson(args, owner, label, options = {}) { + const result = await run("gh", args, { env: ownerEnv(owner), timeoutMs: options.timeoutMs }); + if (!result.ok) { + return { ok: false, value: null, error: { source: label, message: result.message } }; + } + try { + return { ok: true, value: result.stdout.trim() ? JSON.parse(result.stdout) : null, error: null }; + } catch (error) { + return { ok: false, value: null, error: { source: label, message: `Invalid JSON from gh: ${error.message}` } }; + } +} + +/* ---------------- preferences ---------------- */ + +export function normalizePreferences(input) { + const source = input && typeof input === "object" ? input : {}; + const mood = MOODS.includes(source.mood) ? source.mood : DEFAULT_PREFERENCES.mood; + const busyness = BUSYNESS.includes(source.busyness) ? source.busyness : DEFAULT_PREFERENCES.busyness; + const focusIntent = FOCUS_INTENTS.includes(source.focusIntent) ? source.focusIntent : DEFAULT_PREFERENCES.focusIntent; + const minutesNumber = Number(source.minutes); + const minutes = MINUTE_OPTIONS.includes(minutesNumber) ? minutesNumber : DEFAULT_PREFERENCES.minutes; + return { mood, busyness, minutes, focusIntent }; +} + +export async function readPreferences() { + try { + const raw = await readFile(PREFERENCES_PATH, "utf8"); + return normalizePreferences(JSON.parse(raw)); + } catch (error) { + if (error && error.code === "ENOENT") return { ...DEFAULT_PREFERENCES }; + return { ...DEFAULT_PREFERENCES }; + } +} + +export async function writePreferences(input) { + const preferences = normalizePreferences(input); + await mkdir(ARTIFACT_DIR, { recursive: true }); + await writeFile(PREFERENCES_PATH, `${JSON.stringify(preferences, null, 2)}\n`, "utf8"); + return preferences; +} + +export async function setFocusContext(input) { + const normalized = await writePreferences(input); + invalidateCache(); + return normalized; +} + +/* ---------------- repo config ---------------- */ + +function normalizeRepoEntry(entry) { + if (!entry) return null; + const slug = typeof entry === "string" ? entry.trim() : String(entry.slug || "").trim(); + if (!/^[^/\s]+\/[^/\s]+$/.test(slug)) return null; + const weightNumber = Number(entry && entry.weight); + const weight = Number.isFinite(weightNumber) && weightNumber > 0 ? Math.min(3, weightNumber) : 1; + const resolvedPath = entry && typeof entry.path === "string" && entry.path ? entry.path : guessLocalPath(slug); + return { slug, name: nameOf(slug), owner: ownerOf(slug), weight, path: resolvedPath || null }; +} + +function normalizeRepoList(list) { + const seen = new Set(); + const repos = []; + for (const entry of Array.isArray(list) ? list : []) { + const normalized = normalizeRepoEntry(entry); + if (!normalized || seen.has(normalized.slug.toLowerCase())) continue; + seen.add(normalized.slug.toLowerCase()); + repos.push(normalized); + } + return repos; +} + +export async function readConfig() { + try { + const raw = await readFile(CONFIG_PATH, "utf8"); + const parsed = JSON.parse(raw); + const repos = normalizeRepoList(parsed.repos); + return { repos, onboarded: Boolean(parsed.onboarded) || repos.length > 0 }; + } catch (error) { + if (!(error && error.code === "ENOENT")) { + // fall through to seed + } + } + await writeConfig(DEFAULT_CONFIG); + return { ...DEFAULT_CONFIG }; +} + +export async function writeConfig(config) { + const repos = normalizeRepoList(config && config.repos); + const onboarded = Boolean(config && config.onboarded); + await mkdir(ARTIFACT_DIR, { recursive: true }); + await writeFile(CONFIG_PATH, `${JSON.stringify({ repos, onboarded }, null, 2)}\n`, "utf8"); + return { repos, onboarded }; +} + +export async function setTrackedRepos(slugs, onboarded = true) { + const config = await writeConfig({ repos: Array.isArray(slugs) ? slugs : [], onboarded }); + invalidateCache(); + return config; +} + +export async function addRepos(slugs) { + const config = await readConfig(); + const existing = new Set(config.repos.map((repo) => repo.slug.toLowerCase())); + const merged = [...config.repos]; + for (const slug of Array.isArray(slugs) ? slugs : [slugs]) { + const normalized = normalizeRepoEntry(slug); + if (normalized && !existing.has(normalized.slug.toLowerCase())) { + existing.add(normalized.slug.toLowerCase()); + merged.push(normalized); + } + } + const written = await writeConfig({ repos: merged, onboarded: merged.length > 0 || config.onboarded }); + invalidateCache(); + return written; +} + +export async function removeRepos(slugs) { + const config = await readConfig(); + const drop = new Set((Array.isArray(slugs) ? slugs : [slugs]).map((slug) => String(slug).toLowerCase())); + const repos = config.repos.filter((repo) => !drop.has(repo.slug.toLowerCase())); + const written = await writeConfig({ repos, onboarded: config.onboarded && repos.length > 0 }); + invalidateCache(); + return written; +} + +async function listLocalProjects(tracked) { + const seenPaths = new Set(); + const projects = []; + for (const root of LOCAL_PROJECT_DIRS) { + if (!existsSync(root)) continue; + let entries = []; + try { + entries = await readdir(root, { withFileTypes: true }); + } catch { + continue; + } + for (const entry of entries.filter((item) => item.isDirectory()).slice(0, 200)) { + const projectPath = path.join(root, entry.name); + if (seenPaths.has(projectPath) || !existsSync(path.join(projectPath, ".git"))) continue; + seenPaths.add(projectPath); + const remote = await run("git", ["-C", projectPath, "remote", "get-url", "origin"], { timeoutMs: 4000 }); + const slug = remote.ok ? parseRepoSlugFromRemote(remote.stdout) : null; + if (!slug) continue; + projects.push({ + slug, + name: entry.name, + path: projectPath, + source: "local", + description: projectPath, + tracked: tracked.has(slug.toLowerCase()), + }); + } + } + projects.sort((a, b) => a.slug.localeCompare(b.slug)); + return projects; +} + +export async function listAvailableRepos(force = false) { + if (!force && discoveryCache.value && nowMs() - discoveryCache.at < 5 * 60 * 1000) { + return discoveryCache.value; + } + const config = await readConfig(); + const currentLogin = await getCurrentLogin(); + const owners = new Set([currentLogin, ...config.repos.map((repo) => repo.owner)].filter(Boolean)); + const tracked = new Set(config.repos.map((repo) => repo.slug.toLowerCase())); + const errors = []; + const repos = []; + await Promise.all( + [...owners].map(async (owner) => { + const result = await ghJson( + ["repo", "list", owner, "--limit", "100", "--json", "nameWithOwner,description,pushedAt,isArchived,isPrivate,isFork,stargazerCount"], + owner, + `discover:${owner}`, + { timeoutMs: 12000 }, + ); + if (!result.ok) { + if (result.error) errors.push(result.error); + return; + } + for (const item of Array.isArray(result.value) ? result.value : []) { + repos.push({ + slug: item.nameWithOwner, + owner, + description: item.description || "", + pushedAt: item.pushedAt || null, + pushedAgeDays: daysSince(item.pushedAt), + isArchived: Boolean(item.isArchived), + isPrivate: Boolean(item.isPrivate), + isFork: Boolean(item.isFork), + stars: Number(item.stargazerCount || 0), + tracked: tracked.has(String(item.nameWithOwner).toLowerCase()), + }); + } + }), + ); + repos.sort((a, b) => (b.pushedAt || "").localeCompare(a.pushedAt || "")); + const projects = await listLocalProjects(tracked); + const value = { owners: [...owners], repos, projects, errors }; + discoveryCache = { at: nowMs(), value }; + return value; +} + +/* ---------------- sessions ---------------- */ + +async function getCopilotSessions(repos) { + if (!existsSync(SESSION_STORE_PATH)) { + return { sessions: [], errors: [{ source: "copilot-sessions", message: "Session store was not found." }] }; + } + const repoList = repos.map((repo) => `'${repo.slug.replaceAll("'", "''")}'`).join(",") || "''"; + const query = [ + "SELECT id,cwd,repository,branch,summary,created_at,updated_at", + "FROM sessions", + `WHERE repository IN (${repoList})`, + `OR cwd LIKE '${WORKTREES_DIR.replaceAll("'", "''")}/%'`, + "ORDER BY updated_at DESC", + "LIMIT 120", + ].join(" "); + const result = await run("sqlite3", ["-json", SESSION_STORE_PATH, query], { timeoutMs: 8000 }); + if (!result.ok) { + if (/spawn sqlite3 ENOENT/i.test(result.message)) return { sessions: [], errors: [] }; + return { sessions: [], errors: [{ source: "copilot-sessions", message: result.message }] }; + } + try { + const rows = result.stdout.trim() ? JSON.parse(result.stdout) : []; + const normalized = rows.map((row) => ({ + id: row.id, + cwd: row.cwd, + repository: normalizeSessionRepo(row.repository, row.cwd, repos), + branch: row.branch, + summary: row.summary || row.branch || "Open session", + createdAt: row.created_at, + updatedAt: row.updated_at, + ageDays: daysSince(row.updated_at), + })); + const seen = new Set(); + const perRepoCounts = new Map(); + const sessions = []; + for (const item of normalized) { + if (!item.repository) continue; + if (item.ageDays !== null && item.ageDays > 14) continue; + const key = `${item.repository}|${item.branch || ""}|${item.summary || ""}`; + const count = perRepoCounts.get(item.repository) || 0; + if (seen.has(key) || count >= 3) continue; + seen.add(key); + perRepoCounts.set(item.repository, count + 1); + sessions.push(item); + } + return { sessions, errors: [] }; + } catch (error) { + return { sessions: [], errors: [{ source: "copilot-sessions", message: `Invalid session store JSON: ${error.message}` }] }; + } +} + +function normalizeSessionRepo(repository, cwd, repos) { + if (repository) return repository; + if (!cwd) return null; + const match = repos.find((repo) => repo.path && (cwd === repo.path || cwd.startsWith(`${repo.path}/`))); + return match ? match.slug : null; +} + +function stalenessBucket(ageDays) { + if (ageDays === null) return "unknown"; + if (ageDays < 2) return "fresh"; + if (ageDays < 7) return "aging"; + if (ageDays < 30) return "stale"; + return "ancient"; +} + +// Full session inventory for the cleanup tab: no age filter, no per-repo cap. +async function getSessionInventory(repos) { + if (!existsSync(SESSION_STORE_PATH)) { + return { inventory: [], errors: [{ source: "copilot-sessions", message: "Session store was not found." }] }; + } + const repoList = repos.map((repo) => `'${repo.slug.replaceAll("'", "''")}'`).join(",") || "''"; + const query = [ + "SELECT id,cwd,repository,branch,summary,created_at,updated_at", + "FROM sessions", + `WHERE repository IN (${repoList})`, + `OR cwd LIKE '${WORKTREES_DIR.replaceAll("'", "''")}/%'`, + "ORDER BY updated_at DESC", + "LIMIT 400", + ].join(" "); + const result = await run("sqlite3", ["-json", SESSION_STORE_PATH, query], { timeoutMs: 8000 }); + if (!result.ok) { + if (/spawn sqlite3 ENOENT/i.test(result.message)) return { inventory: [], errors: [] }; + return { inventory: [], errors: [{ source: "copilot-sessions", message: result.message }] }; + } + try { + const rows = result.stdout.trim() ? JSON.parse(result.stdout) : []; + const seen = new Set(); + const inventory = []; + for (const row of rows) { + const repository = normalizeSessionRepo(row.repository, row.cwd, repos); + const ageDays = daysSince(row.updated_at); + const isWorktree = Boolean(row.cwd && row.cwd.startsWith(`${WORKTREES_DIR}/`)); + const exists = Boolean(row.cwd && existsSync(row.cwd)); + const key = `${repository || row.cwd || ""}|${row.branch || ""}|${row.summary || ""}`; + if (seen.has(key)) continue; + seen.add(key); + inventory.push({ + id: row.id, + cwd: row.cwd || "", + repository: repository || "(unmapped)", + branch: row.branch || "", + summary: (row.summary || row.branch || "Open session").split("\n")[0].slice(0, 100), + createdAt: row.created_at, + updatedAt: row.updated_at, + ageDays, + ageLabel: ageDays === null ? "unknown" : ageLabel(ageDays), + bucket: stalenessBucket(ageDays), + isWorktree, + orphaned: isWorktree && !exists, + }); + } + return { inventory, errors: [] }; + } catch (error) { + return { inventory: [], errors: [{ source: "copilot-sessions", message: `Invalid session store JSON: ${error.message}` }] }; + } +} + +/* ---------------- local git ---------------- */ + +async function getLocalGitState(repo) { + if (!repo.path || !existsSync(repo.path)) { + return { available: false }; + } + const [statusResult, commitResult] = await Promise.all([ + run("git", ["-C", repo.path, "status", "--short", "--branch", "--untracked-files=no"], { timeoutMs: 8000 }), + run("git", ["-C", repo.path, "log", "-1", "--format=%cI"], { timeoutMs: 8000 }), + ]); + const state = { available: true, path: repo.path }; + if (statusResult.ok) { + const lines = statusResult.stdout.trim().split("\n").filter(Boolean); + state.branchLine = lines[0] || ""; + state.dirtyCount = lines.slice(1).length; + state.ahead = /ahead (\d+)/.exec(state.branchLine)?.[1] ? Number(/ahead (\d+)/.exec(state.branchLine)[1]) : 0; + state.behind = /behind (\d+)/.exec(state.branchLine)?.[1] ? Number(/behind (\d+)/.exec(state.branchLine)[1]) : 0; + } else { + state.error = statusResult.message; + } + if (commitResult.ok) { + state.lastCommitAt = commitResult.stdout.trim() || null; + state.lastCommitAgeDays = daysSince(state.lastCommitAt); + } + return state; +} + +/* ---------------- repo collection ---------------- */ + +async function collectRepo(repo, userLogins, sessionsByRepo) { + const errors = []; + const [metadataResult, releaseResult, tagsResult, prsResult, issuesResult, localGit, deployments] = await Promise.all([ + ghJson(["api", `repos/${repo.slug}`], repo.owner, `${repo.slug}:metadata`), + ghJson(["api", `repos/${repo.slug}/releases/latest`], repo.owner, `${repo.slug}:latest-release`), + ghJson(["api", `repos/${repo.slug}/tags?per_page=1`], repo.owner, `${repo.slug}:latest-tag`), + ghJson( + ["pr", "list", "--repo", repo.slug, "--state", "open", "--limit", "50", "--json", "number,title,author,updatedAt,createdAt,isDraft,reviewDecision,url,headRefName,baseRefName,statusCheckRollup,labels,assignees"], + repo.owner, + `${repo.slug}:prs`, + ), + ghJson( + ["issue", "list", "--repo", repo.slug, "--state", "open", "--limit", "50", "--json", "number,title,author,updatedAt,createdAt,url,labels,assignees,comments"], + repo.owner, + `${repo.slug}:issues`, + ), + getLocalGitState(repo), + getDeployments(repo), + ]); + + for (const result of [metadataResult, prsResult, issuesResult]) { + if (!result.ok && result.error) errors.push(result.error); + } + if (!releaseResult.ok && releaseResult.error && !/Not Found/i.test(releaseResult.error.message)) errors.push(releaseResult.error); + if (!tagsResult.ok && tagsResult.error) errors.push(tagsResult.error); + if (localGit.error) errors.push({ source: `${repo.slug}:local-git`, message: localGit.error }); + if (deployments.error) errors.push(deployments.error); + + const metadata = metadataResult.value || {}; + const prs = Array.isArray(prsResult.value) ? prsResult.value.map((pr) => normalizePr(repo, pr, userLogins)) : []; + const issues = Array.isArray(issuesResult.value) ? issuesResult.value.map((issue) => normalizeIssue(repo, issue, userLogins)) : []; + const latestRelease = releaseResult.ok && releaseResult.value ? normalizeRelease(releaseResult.value, "release") : null; + const latestTag = tagsResult.ok && Array.isArray(tagsResult.value) && tagsResult.value[0] ? normalizeRelease(tagsResult.value[0], "tag") : null; + const release = latestRelease || latestTag; + const releaseAgeDays = release ? daysSince(release.publishedAt) : null; + const pushedAgeDays = daysSince(metadata.pushed_at); + const activeSessions = sessionsByRepo.get(repo.slug) || []; + const needsHumanPrs = prs.filter((pr) => pr.needsHumanReview || pr.requestedFromJames || pr.failingChecks); + const humanIssues = issues.filter((issue) => issue.assignedToJames || issue.isHumanAuthored); + const latestDeploy = deployments.latest || null; + const failedDeploy = deployments.environments.some((env) => ["failure", "error"].includes(env.state)); + + const status = summarizeRepoStatus({ errors, prs, releaseAgeDays, pushedAgeDays, activeSessions, metadata, needsHumanPrs, latestDeploy, failedDeploy }); + + return { + ...repo, + url: metadata.html_url || `https://github.com/${repo.slug}`, + description: metadata.description || repo.description || "", + defaultBranch: metadata.default_branch || "main", + isArchived: Boolean(metadata.archived), + isPrivate: Boolean(metadata.private), + language: metadata.language || "", + stars: Number(metadata.stargazers_count || 0), + pushedAt: metadata.pushed_at || null, + pushedAgeDays, + latestRelease: release, + releaseAgeDays, + releaseAgeLabel: ageLabel(releaseAgeDays), + deployments: deployments.environments, + latestDeploy, + deployAgeDays: latestDeploy ? latestDeploy.ageDays : null, + deployAgeLabel: ageLabel(latestDeploy ? latestDeploy.ageDays : null), + failedDeploy, + openPrCount: prs.length, + openIssueCount: issues.length, + needsHumanPrCount: needsHumanPrs.length, + humanIssueCount: humanIssues.length, + prs, + issues, + localGit, + activeSessions, + status, + errors, + }; +} + +async function getDeployments(repo) { + const list = await ghJson(["api", `repos/${repo.slug}/deployments?per_page=30`], repo.owner, `${repo.slug}:deployments`); + if (!list.ok) { + const error = list.error && /Not Found/i.test(list.error.message) ? null : list.error; + return { environments: [], latest: null, error }; + } + const rows = Array.isArray(list.value) ? list.value : []; + const byEnv = new Map(); + for (const deploy of rows) { + const env = deploy.environment || "unknown"; + const current = byEnv.get(env); + if (!current || new Date(deploy.created_at) > new Date(current.created_at)) byEnv.set(env, deploy); + } + const latestPerEnv = [...byEnv.values()].sort((a, b) => new Date(b.created_at) - new Date(a.created_at)).slice(0, 4); + const environments = await Promise.all( + latestPerEnv.map(async (deploy) => { + const statusResult = await ghJson(["api", `repos/${repo.slug}/deployments/${deploy.id}/statuses?per_page=1`], repo.owner, `${repo.slug}:deploy-status`); + const statusRow = statusResult.ok && Array.isArray(statusResult.value) && statusResult.value[0] ? statusResult.value[0] : null; + return { + environment: deploy.environment || "unknown", + ref: deploy.ref || "", + createdAt: deploy.created_at, + ageDays: daysSince(deploy.created_at), + state: statusRow ? String(statusRow.state || "unknown") : "unknown", + url: statusRow ? statusRow.environment_url || "" : "", + isProduction: Boolean(deploy.production_environment) || /prod|pages|release/i.test(deploy.environment || ""), + }; + }), + ); + return { environments, latest: environments[0] || null, error: null }; +} + +function normalizeRelease(value, kind) { + return { + kind, + name: value.name || value.tag_name || "Latest tag", + tagName: value.tag_name || value.name || "", + publishedAt: value.published_at || value.created_at || value.commit?.committer?.date || null, + url: value.html_url || "", + }; +} + +function normalizePr(repo, pr, userLogins) { + const authorLogin = normalizeLogin(pr.author); + const assignees = Array.isArray(pr.assignees) ? pr.assignees.map(normalizeLogin).filter(Boolean) : []; + const labels = Array.isArray(pr.labels) ? pr.labels.map((label) => label.name || label).filter(Boolean) : []; + const failingChecks = Array.isArray(pr.statusCheckRollup) + ? pr.statusCheckRollup.some((check) => ["FAILURE", "ERROR", "TIMED_OUT", "CANCELLED"].includes(String(check.conclusion || check.status || "").toUpperCase())) + : false; + const assignedToJames = assignees.some((login) => userLogins.has(login.toLowerCase())); + const reviewRequired = pr.reviewDecision === "REVIEW_REQUIRED" || pr.reviewDecision === "CHANGES_REQUESTED"; + const isHumanAuthored = isHumanLogin(authorLogin); + return { + repo: repo.slug, + type: "pr", + number: pr.number, + title: pr.title || `PR #${pr.number}`, + url: pr.url || `https://github.com/${repo.slug}/pull/${pr.number}`, + author: authorLogin, + isHumanAuthored, + createdAt: pr.createdAt, + updatedAt: pr.updatedAt, + updatedAgeDays: daysSince(pr.updatedAt), + isDraft: Boolean(pr.isDraft), + reviewDecision: pr.reviewDecision || "UNKNOWN", + assignedToJames, + requestedFromJames: assignedToJames && reviewRequired, + needsHumanReview: isHumanAuthored && reviewRequired, + failingChecks, + labels, + headRefName: pr.headRefName || "", + baseRefName: pr.baseRefName || "", + }; +} + +function normalizeIssue(repo, issue, userLogins) { + const authorLogin = normalizeLogin(issue.author); + const assignees = Array.isArray(issue.assignees) ? issue.assignees.map(normalizeLogin).filter(Boolean) : []; + const labels = Array.isArray(issue.labels) ? issue.labels.map((label) => label.name || label).filter(Boolean) : []; + const assignedToJames = assignees.some((login) => userLogins.has(login.toLowerCase())); + const isHumanAuthored = isHumanLogin(authorLogin); + return { + repo: repo.slug, + type: "issue", + number: issue.number, + title: issue.title || `Issue #${issue.number}`, + url: issue.url || `https://github.com/${repo.slug}/issues/${issue.number}`, + author: authorLogin, + isHumanAuthored, + assignedToJames, + createdAt: issue.createdAt, + updatedAt: issue.updatedAt, + updatedAgeDays: daysSince(issue.updatedAt), + labels, + comments: Number(issue.comments || 0), + }; +} + +function summarizeRepoStatus(input) { + if (input.metadata.archived) return { tone: "muted", label: "Archived", detail: "Repository is archived." }; + if (input.errors.length >= 3) return { tone: "danger", label: "Needs setup", detail: "Several data sources failed." }; + if (input.failedDeploy) return { tone: "danger", label: "Deploy failed", detail: `Latest ${input.latestDeploy ? input.latestDeploy.environment : "deployment"} did not succeed.` }; + if (input.needsHumanPrs.length > 0) return { tone: "attention", label: "Review needed", detail: `${input.needsHumanPrs.length} PRs need human attention.` }; + if (input.prs.some((pr) => pr.failingChecks)) return { tone: "danger", label: "Checks failing", detail: "Open PR checks need attention." }; + const recentGoodDeploy = input.latestDeploy && input.latestDeploy.state === "success" && input.latestDeploy.ageDays !== null && input.latestDeploy.ageDays <= 30; + if ((input.releaseAgeDays === null || input.releaseAgeDays > 120) && recentGoodDeploy) { + return { tone: "active", label: "Deploying", detail: `Deployed to ${input.latestDeploy.environment} ${ageLabel(input.latestDeploy.ageDays)} ago.` }; + } + if (input.releaseAgeDays === null) return { tone: "neutral", label: "No release", detail: "No release or tag was found." }; + if (input.releaseAgeDays > 120) return { tone: "attention", label: "Release stale", detail: `Last release/tag was ${ageLabel(input.releaseAgeDays)} ago.` }; + if (input.pushedAgeDays !== null && input.pushedAgeDays > 90) return { tone: "neutral", label: "Quiet", detail: `Default branch activity is ${ageLabel(input.pushedAgeDays)} old.` }; + if (input.activeSessions.length > 0) return { tone: "active", label: "Recent work", detail: `${input.activeSessions.length} recent session signals.` }; + return { tone: "good", label: "Healthy", detail: "No urgent signal detected." }; +} + +/* ---------------- focus + recommendations ---------------- */ + +function buildFocusItems(repos, sessions) { + const items = []; + for (const repo of repos) { + for (const pr of repo.prs) { + let score = 20 * repo.weight; + const reasons = []; + const tags = []; + if (pr.requestedFromJames) { score += 70; reasons.push("assigned review"); tags.push("needs-review"); } + else if (pr.needsHumanReview) { score += 45; reasons.push("human review needed"); tags.push("needs-review"); } + if (pr.failingChecks) { score += 30; reasons.push("checks failing"); tags.push("failing-checks"); } + if (pr.isHumanAuthored) tags.push("human"); + if (!pr.isDraft) score += 10; else tags.push("draft"); + if (pr.updatedAgeDays !== null && pr.updatedAgeDays <= 2) { score += 12; reasons.push("recently active"); tags.push("recent"); } + items.push({ + id: `${repo.slug}#pr-${pr.number}`, + kind: "pr", + repo: repo.slug, + number: pr.number, + title: pr.title, + url: pr.url, + score: Math.round(score), + minutes: pr.failingChecks ? 60 : 30, + energy: pr.failingChecks ? "focused" : "medium", + reasons, + what: `Review PR #${pr.number} and decide whether it needs feedback, fixes, or merge attention.`, + how: pr.failingChecks ? "Open the PR detail, inspect failing checks first, then request a Copilot review or jump into an implementation session if the failure needs code." : "Open the PR detail, scan the summary and comments, then approve/request changes or ask Copilot for a review.", + tags, + updatedAgeDays: pr.updatedAgeDays, + detail: `PR #${pr.number} by ${pr.author || "unknown"} · ${pr.reviewDecision}`, + }); + } + for (const issue of repo.issues) { + let score = 12 * repo.weight; + const reasons = []; + const tags = []; + if (issue.assignedToJames) { score += 55; reasons.push("assigned to you"); tags.push("assigned"); } + if (issue.isHumanAuthored) { score += 18; reasons.push("human issue"); tags.push("human"); } + if (issue.comments > 0) score += Math.min(14, issue.comments * 2); + if (issue.updatedAgeDays !== null && issue.updatedAgeDays <= 3) { score += 10; tags.push("recent"); } + items.push({ + id: `${repo.slug}#issue-${issue.number}`, + kind: "issue", + repo: repo.slug, + number: issue.number, + title: issue.title, + url: issue.url, + score: Math.round(score), + minutes: 30, + energy: "medium", + reasons, + what: `Triage issue #${issue.number} and choose whether it is ready for implementation, needs clarification, or should become a cloud session.`, + how: issue.assignedToJames ? "Because it is assigned to you, start by reading the latest comments, then assign it to a cloud session or open a local implementation plan." : "Read the description and recent comments, refine the spec if it is fuzzy, or assign it when it is actionable.", + tags, + updatedAgeDays: issue.updatedAgeDays, + detail: `Issue #${issue.number} by ${issue.author || "unknown"} · ${issue.comments} comments`, + }); + } + if (repo.releaseAgeDays === null || repo.releaseAgeDays > 120) { + const staleScore = repo.releaseAgeDays === null ? 24 : Math.min(65, 20 + Math.floor(repo.releaseAgeDays / 12)); + items.push({ + id: `${repo.slug}#release`, + kind: "release", + repo: repo.slug, + title: repo.releaseAgeDays === null ? "Establish release baseline" : `Review stale release cadence (${ageLabel(repo.releaseAgeDays)})`, + url: repo.url, + score: Math.round(staleScore * repo.weight), + minutes: 60, + energy: "focused", + reasons: [repo.releaseAgeDays === null ? "no release/tag" : "release stale"], + what: repo.releaseAgeDays === null ? "Create a release baseline so the repo has a known published state." : "Review whether the release cadence is stale and decide if current main is ready to ship.", + how: "Check recent commits, tags, and deployments, then either cut a release/tag or record what is blocking the next one.", + tags: ["stale-release"], + updatedAgeDays: repo.releaseAgeDays, + detail: repo.latestRelease ? `Latest ${repo.latestRelease.kind}: ${repo.latestRelease.tagName || repo.latestRelease.name}` : "No release or tag detected", + }); + } + if (repo.failedDeploy && repo.latestDeploy) { + items.push({ + id: `${repo.slug}#deploy`, + kind: "deploy", + repo: repo.slug, + title: `Fix failed deployment to ${repo.latestDeploy.environment}`, + url: repo.latestDeploy.url || repo.url, + score: Math.round(75 * repo.weight), + minutes: 60, + energy: "focused", + reasons: ["deployment failed"], + what: `Investigate the failed ${repo.latestDeploy.environment} deployment and decide if it blocks shipping.`, + how: "Open the deployment, inspect the failed status/logs, then create a fix session if the failure points to code or configuration.", + tags: ["failing-deploy"], + updatedAgeDays: repo.latestDeploy.ageDays, + detail: `${repo.latestDeploy.environment} · ${repo.latestDeploy.state} · ${ageLabel(repo.latestDeploy.ageDays)} ago`, + }); + } + } + for (const recentSession of sessions.filter((entry) => entry.repository)) { + if (recentSession.ageDays !== null && recentSession.ageDays > 7) continue; + const staleSession = recentSession.ageDays !== null && recentSession.ageDays >= 2; + const sessionLabel = (recentSession.summary || "open session").split("\n")[0].trim().slice(0, 80); + items.push({ + id: `${recentSession.id}#session`, + kind: "session", + repo: recentSession.repository, + sessionId: recentSession.id, + branch: recentSession.branch || "", + title: `Triage session: ${sessionLabel}`, + url: "", + score: Math.max(18, 46 - (recentSession.ageDays || 0) * 4) + (staleSession ? 10 : 0), + minutes: 15, + energy: "low", + reasons: [staleSession ? "session left open, needs triage" : "recent session to triage"], + what: "Triage an existing coding session so active work does not go stale.", + how: "Jump to the session, read the latest agent state, then decide whether to continue, close, or clean it up.", + tags: staleSession ? ["triage", "active-session", "stale-session"] : ["triage", "active-session"], + updatedAgeDays: recentSession.ageDays, + detail: `${recentSession.branch || "unknown branch"} · updated ${ageLabel(recentSession.ageDays)} ago`, + }); + } + return items.sort((a, b) => b.score - a.score); +} + +function adjustScore(item, preferences) { + let score = item.score; + if (preferences.focusIntent === "prs") { + if (item.kind === "pr") score += 45; + if (item.tags.includes("needs-review") || item.tags.includes("failing-checks")) score += 18; + if (item.kind === "issue") score -= 8; + } + if (preferences.focusIntent === "new-code") { + if (item.kind === "issue") score += 40; + if (item.tags.includes("assigned")) score += 15; + if (item.kind === "deploy" || item.kind === "release") score += 8; + if (item.kind === "pr" && !item.tags.includes("failing-checks")) score -= 10; + } + if (preferences.focusIntent === "issue-triage") { + if (item.kind === "issue") score += 45; + if (item.tags.includes("human") || item.tags.includes("recent")) score += 12; + if (item.kind === "pr") score -= 12; + } + if (preferences.focusIntent === "maintenance") { + if (["release", "deploy", "session"].includes(item.kind)) score += 42; + if (item.tags.includes("stale-session") || item.tags.includes("stale-release")) score += 15; + if (item.kind === "issue" && !item.tags.includes("assigned")) score -= 10; + } + if (preferences.mood === "low-energy") { + if (item.minutes <= 15 || item.energy === "low") score += 25; + if (item.kind === "release" || item.energy === "focused") score -= 20; + } + if (preferences.mood === "maintenance" && ["issue", "release", "session"].includes(item.kind)) score += 22; + if (preferences.mood === "creative") { + if (["release", "session"].includes(item.kind)) score += 18; + if (item.kind === "pr") score -= 6; + } + if (preferences.mood === "urgent") { + if (item.kind === "pr" || item.tags.includes("failing-checks")) score += 32; + if (item.minutes > preferences.minutes) score -= 10; + } + if (preferences.mood === "focused" && item.energy === "focused") score += 16; + if (preferences.busyness === "busy") { + if (item.minutes <= 15) score += 24; + if (item.minutes >= 60) score -= 24; + } + if (preferences.busyness === "open" && item.minutes >= 60) score += 12; + return Math.round(score); +} + +function buildRecommendations(items, preferences) { + const adjusted = items.map((item) => ({ ...item, adjustedScore: adjustScore(item, preferences) })).sort((a, b) => b.adjustedScore - a.adjustedScore); + const maxItems = preferences.minutes <= 15 ? 2 : preferences.minutes <= 30 ? 3 : preferences.minutes <= 60 ? 4 : 6; + let remaining = preferences.minutes; + const picks = []; + for (const item of adjusted) { + if (picks.length >= maxItems) break; + const cost = Math.min(item.minutes, remaining); + if (cost <= 0) break; + if (item.minutes > remaining && preferences.minutes !== 15) continue; + picks.push({ ...item, plannedMinutes: cost }); + remaining -= cost; + } + if (picks.length === 0 && adjusted[0]) { + picks.push({ ...adjusted[0], plannedMinutes: Math.min(preferences.minutes, adjusted[0].minutes) }); + } + return picks; +} + +function summarizeDashboard(repos, sessions, focusItems, errors, inventory = []) { + return { + repoCount: repos.length, + openPrCount: repos.reduce((sum, repo) => sum + repo.openPrCount, 0), + openIssueCount: repos.reduce((sum, repo) => sum + repo.openIssueCount, 0), + needsHumanPrCount: repos.reduce((sum, repo) => sum + repo.needsHumanPrCount, 0), + humanIssueCount: repos.reduce((sum, repo) => sum + repo.humanIssueCount, 0), + staleReleaseCount: repos.filter((repo) => repo.releaseAgeDays === null || repo.releaseAgeDays > 120).length, + failedDeployCount: repos.filter((repo) => repo.failedDeploy).length, + deployedRepoCount: repos.filter((repo) => repo.latestDeploy).length, + activeSessionCount: sessions.filter((entry) => entry.repository && (entry.ageDays === null || entry.ageDays <= 14)).length, + sessionInventoryCount: inventory.length, + staleSessionCount: inventory.filter((s) => s.bucket === "stale" || s.bucket === "ancient" || s.orphaned).length, + topFocusCount: focusItems.length, + errorCount: errors.length, + }; +} + +/* ---------------- item detail + actions ---------------- */ + +function normalizeComments(rows) { + if (!Array.isArray(rows)) return []; + return rows.slice(-8).map((c) => ({ + author: normalizeLogin(c.author), + body: String(c.body || "").slice(0, 2000), + createdAt: c.createdAt || c.created_at || null, + ageDays: daysSince(c.createdAt || c.created_at), + url: c.url || "", + })); +} + +export async function getItemDetail({ repo, type, number } = {}) { + const slug = String(repo || ""); + const owner = ownerOf(slug); + const num = Number(number); + if (!slug.includes("/") || !num || !["pr", "issue"].includes(type)) { + throw new Error("A repo slug, item type (pr|issue), and number are required."); + } + if (type === "pr") { + const fields = "number,title,body,state,author,url,isDraft,reviewDecision,labels,assignees,additions,deletions,changedFiles,mergeable,mergeStateStatus,comments,createdAt,updatedAt,headRefName,baseRefName,statusCheckRollup"; + const result = await ghJson(["pr", "view", String(num), "--repo", slug, "--json", fields], owner, `${slug}#pr-${num}:detail`); + if (!result.ok || !result.value) throw new Error(result.error?.message || "Could not load pull request."); + const pr = result.value; + const checks = Array.isArray(pr.statusCheckRollup) ? pr.statusCheckRollup : []; + const failing = checks.filter((c) => ["FAILURE", "ERROR", "TIMED_OUT", "CANCELLED"].includes(String(c.conclusion || c.status || "").toUpperCase())); + return { + type: "pr", + repo: slug, + number: pr.number, + title: pr.title || `PR #${num}`, + body: String(pr.body || "").slice(0, 6000), + state: pr.state, + isDraft: Boolean(pr.isDraft), + author: normalizeLogin(pr.author), + url: pr.url, + reviewDecision: pr.reviewDecision || "UNKNOWN", + labels: (pr.labels || []).map((l) => l.name || l).filter(Boolean), + assignees: (pr.assignees || []).map(normalizeLogin).filter(Boolean), + additions: pr.additions ?? null, + deletions: pr.deletions ?? null, + changedFiles: pr.changedFiles ?? null, + mergeable: pr.mergeable || "UNKNOWN", + mergeStateStatus: pr.mergeStateStatus || "", + headRefName: pr.headRefName || "", + baseRefName: pr.baseRefName || "", + checksTotal: checks.length, + checksFailing: failing.length, + createdAt: pr.createdAt, + updatedAt: pr.updatedAt, + ageDays: daysSince(pr.updatedAt), + comments: normalizeComments(pr.comments), + }; + } + const fields = "number,title,body,state,author,url,labels,assignees,comments,createdAt,updatedAt"; + const result = await ghJson(["issue", "view", String(num), "--repo", slug, "--json", fields], owner, `${slug}#issue-${num}:detail`); + if (!result.ok || !result.value) throw new Error(result.error?.message || "Could not load issue."); + const issue = result.value; + return { + type: "issue", + repo: slug, + number: issue.number, + title: issue.title || `Issue #${num}`, + body: String(issue.body || "").slice(0, 6000), + state: issue.state, + author: normalizeLogin(issue.author), + url: issue.url, + labels: (issue.labels || []).map((l) => l.name || l).filter(Boolean), + assignees: (issue.assignees || []).map(normalizeLogin).filter(Boolean), + createdAt: issue.createdAt, + updatedAt: issue.updatedAt, + ageDays: daysSince(issue.updatedAt), + comments: normalizeComments(issue.comments), + }; +} + +const ITEM_ACTIONS = { + comment: { verb: "comment", needsBody: true, both: true }, + close: { verb: "close", both: true }, + reopen: { verb: "reopen", both: true }, + "assign-me": { verb: "edit", issueOnly: true, extra: ["--add-assignee", "@me"] }, + "unassign-me": { verb: "edit", issueOnly: true, extra: ["--remove-assignee", "@me"] }, + "request-me": { verb: "edit", prOnly: true, extra: ["--add-reviewer", "@me"] }, + "copilot-review": { prOnly: true, api: true }, + ready: { verb: "ready", prOnly: true }, + approve: { verb: "review", prOnly: true, extra: ["--approve"] }, + merge: { verb: "merge", prOnly: true, extra: ["--squash"] }, +}; + +export async function runItemAction({ repo, type, number, action, body } = {}) { + const slug = String(repo || ""); + const owner = ownerOf(slug); + const num = Number(number); + if (!slug.includes("/") || !num || !["pr", "issue"].includes(type)) { + throw new Error("A repo slug, item type (pr|issue), and number are required."); + } + const spec = ITEM_ACTIONS[action]; + if (!spec) throw new Error(`Unknown action: ${action}`); + if (spec.prOnly && type !== "pr") throw new Error("That action only applies to pull requests."); + if (spec.issueOnly && type !== "issue") throw new Error("That action only applies to issues."); + if (spec.api && action === "copilot-review") { + const apiArgs = ["api", "--method", "POST", `repos/${slug}/pulls/${num}/requested_reviewers`, "-f", "reviewers[]=copilot-pull-request-reviewer[bot]"]; + const apiResult = await run("gh", apiArgs, { env: ownerEnv(owner) }); + if (!apiResult.ok) throw new Error(apiResult.message || "Could not request a Copilot review. Copilot code review may not be enabled for this repo."); + invalidateCache(); + return { ok: true, action, output: "Requested a review from Copilot." }; + } + const args = [type, spec.verb, String(num), "--repo", slug]; + if (spec.needsBody) { + const text = String(body || "").trim(); + if (!text) throw new Error("A comment body is required."); + args.push("--body", text); + } + if (spec.extra) args.push(...spec.extra); + const result = await run("gh", args, { env: ownerEnv(owner) }); + if (!result.ok) throw new Error(result.message || "Action failed."); + invalidateCache(); + return { ok: true, action, output: (result.stdout || "").trim() || `${action} succeeded.` }; +} + +/* ---------------- orchestration ---------------- */ + +export function invalidateCache() { + cachedModel = null; + cachedAt = 0; +} + +export async function collectDashboardState(force = false) { + if (!force && cachedModel && nowMs() - cachedAt < CACHE_TTL_MS) return cachedModel; + if (refreshPromise) return refreshPromise; + refreshPromise = (async () => { + const [preferences, config] = await Promise.all([readPreferences(), readConfig()]); + const [currentLogin, sessionState] = await Promise.all([getCurrentLogin(), getCopilotSessions(config.repos)]); + const sessionInventoryState = await getSessionInventory(config.repos); + const userLogins = knownUserLogins(currentLogin); + const sessionsByRepo = new Map(); + for (const recentSession of sessionState.sessions) { + if (!recentSession.repository) continue; + const list = sessionsByRepo.get(recentSession.repository) || []; + list.push(recentSession); + sessionsByRepo.set(recentSession.repository, list); + } + const repos = await Promise.all(config.repos.map((repo) => collectRepo(repo, userLogins, sessionsByRepo))); + const focusItems = buildFocusItems(repos, sessionState.sessions); + const recommendations = buildRecommendations(focusItems, preferences); + const errors = [...sessionState.errors, ...repos.flatMap((repo) => repo.errors.map((error) => ({ ...error, repo: repo.slug })))]; + cachedModel = { + generatedAt: new Date().toISOString(), + onboarded: config.onboarded && config.repos.length > 0, + preferences, + currentLogin, + options: { moods: MOODS, busyness: BUSYNESS, minutes: MINUTE_OPTIONS, focusIntents: FOCUS_INTENTS }, + summary: summarizeDashboard(repos, sessionState.sessions, focusItems, errors, sessionInventoryState.inventory), + repos, + sessions: sessionState.sessions, + sessionInventory: sessionInventoryState.inventory, + focusItems, + recommendations, + errors, + }; + cachedAt = nowMs(); + refreshPromise = null; + return cachedModel; + })(); + try { + return await refreshPromise; + } catch (error) { + refreshPromise = null; + throw error; + } +} + +async function getCurrentLogin() { + const result = await ghJson(["api", "user"], "", "current-user", { timeoutMs: 8000 }); + return result.ok && result.value && result.value.login ? result.value.login : null; +} diff --git a/extensions/work-hub/extension.mjs b/extensions/work-hub/extension.mjs new file mode 100644 index 00000000..4cc16bb8 --- /dev/null +++ b/extensions/work-hub/extension.mjs @@ -0,0 +1,376 @@ +import { createServer } from "node:http"; +import { joinSession, createCanvas, CanvasError } from "@github/copilot-sdk/extension"; +import { + MOODS, + BUSYNESS, + MINUTE_OPTIONS, + FOCUS_INTENTS, + collectDashboardState, + setFocusContext, + listAvailableRepos, + setTrackedRepos, + addRepos, + removeRepos, + readConfig, + getItemDetail, + runItemAction, +} from "./data.mjs"; +import { renderHtml } from "./renderer.mjs"; + +let sessionRef = null; + +const servers = new Map(); + +function writeJson(res, value, status = 200) { + const body = JSON.stringify(value); + res.writeHead(status, { "Content-Type": "application/json; charset=utf-8", "Content-Length": Buffer.byteLength(body), "Cache-Control": "no-store" }); + res.end(body); +} + +function writeHtml(res, html) { + res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store" }); + res.end(html); +} + +function readBody(req) { + return new Promise((resolve, reject) => { + let body = ""; + req.on("data", (chunk) => { + body += chunk; + if (body.length > 64 * 1024) { + reject(new Error("Request body is too large.")); + req.destroy(); + } + }); + req.on("end", () => { + if (!body) return resolve({}); + try { + resolve(JSON.parse(body)); + } catch (error) { + reject(new Error(`Invalid JSON body: ${error.message}`)); + } + }); + req.on("error", reject); + }); +} + +function normalizePromptText(value) { + return String(value || "").replace(/\r?\n/g, " ").trim(); +} + +function escapePromptValue(value) { + return normalizePromptText(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"'); +} + +function broadcast(entry, event, data) { + const body = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`; + for (const client of entry.clients) { + try { + client.write(body); + } catch { + entry.clients.delete(client); + try { + client.end(); + } catch { + // Ignore cleanup failures for already-disconnected SSE clients. + } + } + } +} + +async function requestItemSession(input = {}) { + const repo = normalizePromptText(input.repo); + const number = Number(input.number); + const type = input.type === "pr" ? "pr" : "issue"; + const title = normalizePromptText(String(input.title || "").slice(0, 160)); + if (!repo.includes("/") || !number) throw new Error("A repo slug and number are required."); + if (!sessionRef) throw new Error("Session bridge is unavailable."); + + const requested = ["implement", "spec", "cloud"].includes(input.mode) ? input.mode : "plan"; + if (requested === "cloud" && type !== "issue") throw new Error("Cloud session assignment is available for issues only."); + + const ref = type === "pr" ? "pull request" : "issue"; + const mode = requested === "spec" && type === "pr" ? "plan" : requested; + const safeRepo = escapePromptValue(repo); + const safeTitleSuffix = title ? ` ("${escapePromptValue(title)}")` : ""; + let prompt; + let label; + if (mode === "cloud") { + prompt = `Create a cloud coding session for issue #${number} in "${safeRepo}"${safeTitleSuffix}. Do not create a local session. First call list_projects and find the configured project whose GitHub repo is exactly "${safeRepo}". If no configured project exists, tell me plainly that this repo is not configured for cloud sessions. If it exists, call create_session with execution_location "cloud", notify_on_idle "once", a short name based on issue #${number}, and kickoff mode "autopilot". The kickoff prompt should tell the cloud agent to read the GitHub issue, understand the requirements, implement the fix end-to-end in that repository, run the existing validation, and report blockers or the resulting PR/session status.`; + label = "cloud"; + } else if (mode === "implement") { + prompt = `Open a new coding session for ${ref} #${number} in "${safeRepo}"${safeTitleSuffix}. Use the appropriate session-creation tool for the "${safeRepo}" project in interactive/implementation mode, and have it begin implementing the ${ref} directly (reading the ${ref} first for context).`; + label = "build"; + } else if (mode === "spec") { + prompt = `Open a new coding session for issue #${number} in "${safeRepo}"${safeTitleSuffix}. Use the appropriate session-creation tool for the "${safeRepo}" project in plan mode. Do NOT implement code — instead have it refine and sharpen the issue's specification: read the issue, clarify goals, scope, acceptance criteria, edge cases, and open questions, then propose an updated, well-structured spec and offer to post it back as a comment on the issue.`; + label = "spec-refinement"; + } else { + prompt = `Open a new coding session for ${ref} #${number} in "${safeRepo}"${safeTitleSuffix}. Use the appropriate session-creation tool for the "${safeRepo}" project, kick it off in plan mode, and have it start by understanding the ${ref} and proposing an implementation plan.`; + label = "planning"; + } + await sessionRef.send(prompt); + return { ok: true, message: `Requested a ${mode === "cloud" ? "cloud coding" : label} session for ${repo} #${number}.` }; +} + +async function handleRequest(entry, req, res) { + const url = new URL(req.url || "/", "http://127.0.0.1"); + const p = url.pathname; + try { + if (req.method === "GET" && p === "/") return writeHtml(res, renderHtml()); + if (req.method === "GET" && p === "/api/state") return writeJson(res, await collectDashboardState(url.searchParams.get("force") === "1")); + if (req.method === "GET" && p === "/api/available-repos") return writeJson(res, await listAvailableRepos(url.searchParams.get("force") === "1")); + + if (req.method === "POST" && p === "/api/refresh") { + const model = await collectDashboardState(true); + broadcast(entry, "state", { generatedAt: model.generatedAt }); + return writeJson(res, model); + } + if (req.method === "POST" && p === "/api/focus") { + await setFocusContext(await readBody(req)); + const model = await collectDashboardState(true); + broadcast(entry, "state", { generatedAt: model.generatedAt }); + return writeJson(res, model); + } + if (req.method === "POST" && p === "/api/repos/add") { + const input = await readBody(req); + await addRepos(input.repos || input.slug || input.slugs); + return writeJson(res, await readConfig()); + } + if (req.method === "POST" && p === "/api/repos/remove") { + const input = await readBody(req); + await removeRepos(input.slug || input.slugs); + return writeJson(res, await readConfig()); + } + if (req.method === "POST" && p === "/api/repos/set") { + const input = await readBody(req); + await setTrackedRepos(input.repos || input.slugs, input.onboarded !== false); + return writeJson(res, await readConfig()); + } + if (req.method === "GET" && p === "/api/item") { + return writeJson(res, await getItemDetail({ + repo: url.searchParams.get("repo"), + type: url.searchParams.get("type"), + number: url.searchParams.get("number"), + })); + } + if (req.method === "POST" && p === "/api/item/action") { + const input = await readBody(req); + const result = await runItemAction(input); + broadcast(entry, "state", { generatedAt: new Date().toISOString() }); + return writeJson(res, result); + } + if (req.method === "POST" && p === "/api/item/session") { + const input = await readBody(req); + return writeJson(res, await requestItemSession(input)); + } + + if (req.method === "POST" && p === "/api/session/jump") { + const input = await readBody(req); + const id = String(input.sessionId || ""); + if (!id) throw new Error("A sessionId is required."); + if (!sessionRef) throw new Error("Session bridge is unavailable."); + const repo = normalizePromptText(input.repo); + const branch = normalizePromptText(input.branch); + const where = repo ? ` in ${repo}` : ""; + const branchNote = branch ? ` on branch "${escapePromptValue(branch)}"` : ""; + const prompt = `I want to jump to my active coding session${where}${branchNote} to triage it. Call list_sessions_and_chats, find the session whose project_repo matches "${escapePromptValue(repo)}"${branch ? ` and whose path/branch matches "${escapePromptValue(branch)}"` : ""}, then call navigate_to with that session's id. (The session-store id is ${id}, but use the id from list_sessions_and_chats since the app navigation id can differ.) If no matching session is found, tell me it may have been closed.`; + await sessionRef.send(prompt); + return writeJson(res, { ok: true, message: "Jumping to that session…" }); + } + + if (req.method === "POST" && p === "/api/session/cleanup") { + const input = await readBody(req); + if (!sessionRef) throw new Error("Session bridge is unavailable."); + const list = Array.isArray(input.sessions) ? input.sessions.filter((s) => s && s.repo) : []; + if (!list.length) throw new Error("No sessions were provided to clean up."); + const lines = list.slice(0, 40).map((s, i) => `${i + 1}. repo "${escapePromptValue(s.repo)}"${s.branch ? `, branch "${escapePromptValue(s.branch)}"` : ""}${s.summary ? ` — summary "${escapePromptValue(s.summary)}"` : ""}${s.ageLabel ? ` (last active "${escapePromptValue(s.ageLabel)}" ago)` : ""}${s.archived ? " [ARCHIVED: worktree already removed]" : ""}`).join("\n"); + const prompt = `I want to clean up ${list.length} old coding session${list.length === 1 ? "" : "s"} from Work Hub. For each one below, call list_sessions_and_chats and match the real app session by project_repo (and branch/path where given), then show me exactly which app sessions you'll delete and ask me to confirm before calling delete_item. Never delete without my explicit confirmation, and skip any that don't clearly match or that appear to have uncommitted work worth keeping. Items marked [ARCHIVED] no longer have a worktree and are very likely already closed — if you can't find a matching live session for one, tell me it's already gone rather than treating it as an error.\n\nSessions to clean up:\n${lines}`; + await sessionRef.send(prompt); + return writeJson(res, { ok: true, message: `Requested cleanup of ${list.length} session${list.length === 1 ? "" : "s"} (pending your confirmation).` }); + } + + if (req.method === "GET" && p === "/events") { + res.writeHead(200, { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive" }); + entry.clients.add(res); + res.write(`event: ready\ndata: ${JSON.stringify({ ok: true })}\n\n`); + req.on("close", () => entry.clients.delete(res)); + return; + } + writeJson(res, { error: "Not found" }, 404); + } catch (error) { + writeJson(res, { error: error.message || "Request failed" }, 500); + } +} + +async function startServer(instanceId) { + const entry = { server: null, url: "", clients: new Set(), instanceId }; + const server = createServer((req, res) => handleRequest(entry, req, res)); + await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); + const address = server.address(); + const port = typeof address === "object" && address ? address.port : 0; + entry.server = server; + entry.url = `http://127.0.0.1:${port}/`; + return entry; +} + +sessionRef = await joinSession({ + canvases: [ + createCanvas({ + id: "work-hub", + displayName: "Work Hub", + description: "Generic cross-repo command center with onboarding, configurable repos/projects, repo health, and focus recommendations.", + inputSchema: { + type: "object", + additionalProperties: false, + properties: { + mood: { type: "string", enum: MOODS }, + minutes: { type: "number", enum: MINUTE_OPTIONS }, + busyness: { type: "string", enum: BUSYNESS }, + focusIntent: { type: "string", enum: FOCUS_INTENTS }, + }, + }, + actions: [ + { + name: "refresh", + description: "Refresh GitHub, local git, session, and recommendation data for Work Hub.", + inputSchema: { type: "object", additionalProperties: false, properties: { force: { type: "boolean" } } }, + handler: async (ctx) => collectDashboardState(ctx.input?.force !== false), + }, + { + name: "get_state", + description: "Return the current Work Hub dashboard state, using the short cache when fresh.", + inputSchema: { type: "object", additionalProperties: false, properties: {} }, + handler: async () => collectDashboardState(false), + }, + { + name: "set_focus_context", + description: "Set mood, available time, and busyness, then return updated focus recommendations.", + inputSchema: { + type: "object", + additionalProperties: false, + required: ["mood", "minutes", "busyness"], + properties: { + mood: { type: "string", enum: MOODS }, + minutes: { type: "number", enum: MINUTE_OPTIONS }, + busyness: { type: "string", enum: BUSYNESS }, + focusIntent: { type: "string", enum: FOCUS_INTENTS }, + }, + }, + handler: async (ctx) => { + if (!ctx.input || typeof ctx.input !== "object") throw new CanvasError("invalid_focus_context", "Focus context input is required."); + await setFocusContext(ctx.input); + return collectDashboardState(true); + }, + }, + { + name: "assign_issue_to_cloud_session", + description: "Ask the host agent to create a cloud coding session for a GitHub issue.", + inputSchema: { + type: "object", + additionalProperties: false, + required: ["repo", "number"], + properties: { + repo: { type: "string" }, + number: { type: "number" }, + title: { type: "string" }, + }, + }, + handler: async (ctx) => requestItemSession({ ...ctx.input, type: "issue", mode: "cloud" }), + }, + { + name: "list_available_repos", + description: "Discover repositories from your GitHub account that can be tracked in the hub.", + inputSchema: { type: "object", additionalProperties: false, properties: { force: { type: "boolean" } } }, + handler: async (ctx) => listAvailableRepos(Boolean(ctx.input?.force)), + }, + { + name: "set_tracked_repos", + description: "Replace the tracked repository list with the provided owner/repo slugs.", + inputSchema: { + type: "object", + additionalProperties: false, + properties: { + slugs: { type: "array", items: { type: "string" } }, + repos: { + type: "array", + items: { + type: "object", + additionalProperties: false, + required: ["slug"], + properties: { slug: { type: "string" }, path: { type: "string" }, weight: { type: "number" } }, + }, + }, + }, + }, + handler: async (ctx) => { + const repos = ctx.input?.repos || ctx.input?.slugs || []; + if (!repos.length) throw new CanvasError("invalid_repo", "Provide slugs or repos to track."); + await setTrackedRepos(repos); + return collectDashboardState(true); + }, + }, + { + name: "add_repo", + description: "Track one or more repositories by owner/repo slug.", + inputSchema: { + type: "object", + additionalProperties: false, + properties: { + slug: { type: "string" }, + slugs: { type: "array", items: { type: "string" } }, + repos: { + type: "array", + items: { + type: "object", + additionalProperties: false, + required: ["slug"], + properties: { slug: { type: "string" }, path: { type: "string" }, weight: { type: "number" } }, + }, + }, + }, + }, + handler: async (ctx) => { + const slugs = ctx.input?.repos || ctx.input?.slugs || (ctx.input?.slug ? [ctx.input.slug] : []); + if (!slugs.length) throw new CanvasError("invalid_repo", "Provide a slug or slugs to add."); + await addRepos(slugs); + return collectDashboardState(true); + }, + }, + { + name: "remove_repo", + description: "Stop tracking one or more repositories by owner/repo slug.", + inputSchema: { + type: "object", + additionalProperties: false, + properties: { + slug: { type: "string" }, + slugs: { type: "array", items: { type: "string" } }, + }, + }, + handler: async (ctx) => { + const slugs = ctx.input?.slugs || (ctx.input?.slug ? [ctx.input.slug] : []); + if (!slugs.length) throw new CanvasError("invalid_repo", "Provide a slug or slugs to remove."); + await removeRepos(slugs); + return collectDashboardState(true); + }, + }, + ], + open: async (ctx) => { + if (ctx.input && Object.keys(ctx.input).length > 0) await setFocusContext(ctx.input); + let entry = servers.get(ctx.instanceId); + if (!entry) { + entry = await startServer(ctx.instanceId); + servers.set(ctx.instanceId, entry); + } + return { title: "Work Hub", status: "Cross-repo command center", url: entry.url }; + }, + onClose: async (ctx) => { + const entry = servers.get(ctx.instanceId); + if (!entry) return; + servers.delete(ctx.instanceId); + for (const client of entry.clients) client.end(); + await new Promise((resolve) => entry.server.close(() => resolve())); + }, + }), + ], +}); diff --git a/extensions/work-hub/package.json b/extensions/work-hub/package.json new file mode 100644 index 00000000..daf4d36d --- /dev/null +++ b/extensions/work-hub/package.json @@ -0,0 +1,18 @@ +{ + "name": "work-hub", + "version": "1.0.0", + "type": "module", + "main": "extension.mjs", + "description": "Generic cross-repo command center canvas for GitHub Copilot with onboarding, focus planning, repo health, work signals, and session cleanup.", + "keywords": [ + "cross-repo-dashboard", + "focus-planning", + "repo-health", + "session-cleanup", + "work-triage", + "workflow-visibility" + ], + "dependencies": { + "@github/copilot-sdk": "latest" + } +} diff --git a/extensions/work-hub/renderer.mjs b/extensions/work-hub/renderer.mjs new file mode 100644 index 00000000..bcaeea54 --- /dev/null +++ b/extensions/work-hub/renderer.mjs @@ -0,0 +1,1138 @@ +export function renderHtml() { + return ` + + + + +Work Hub + + + +
+
+
+
+ +
+

Work Hub

+

Loading your command center…

+
+
+
+ + + + + +
+
+ +
+ +
+
+
+
+
+
Building a plan for your available time…
+
+
+
+ +
+
+ + + +
+
+
+
+ +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+
+ + 0 selected + + + +
+
+
+ +
+
+
+ + + +
+
Tracked repos are stored in ~/.copilot/extensions/work-hub/artifacts/config.json. Local checkouts under ~/Projects are auto-detected.
+
+

Tracked (0)

+
+

Discover your repos

+
+
Open this tab to load your repositories.
+
+ +
+
+ Data quality (0 warnings) +
+
+
+
+
+
+
+ + +`; +} + +function clientScript() { + return ` +const state = { model: null, tab: "focus", loading: false, discover: null, discoverLoading: false, + filters: { text: "", repo: "", sort: "priority", chips: new Set(), repoText: "", repoSort: "attention", discoverText: "" }, + cleanup: { text: "", repo: "", sort: "oldest", buckets: new Set(), selected: new Set() }, + onboarding: { selected: new Set() } }; +const $ = (id) => document.getElementById(id); +const esc = (v) => String(v ?? "").replace(/[&<>"']/g, (c) => ({ "&":"&","<":"<",">":">",'"':""","'":"'" }[c])); + +const CHIP_DEFS = [ + { id: "open-pr", label: "Open PRs", kind: "pr" }, + { id: "open-issue", label: "Open issues", kind: "issue" }, + { id: "needs-review", label: "Needs review" }, + { id: "human", label: "Human authored" }, + { id: "failing-checks", label: "Failing checks" }, + { id: "assigned", label: "Assigned to me" }, + { id: "stale-release", label: "Stale release" }, + { id: "failing-deploy", label: "Failed deploy" }, + { id: "active-session", label: "Active session" }, + { id: "triage", label: "Session triage" }, +]; +const CHIP_KINDS = Object.fromEntries(CHIP_DEFS.filter((c) => c.kind).map((c) => [c.id, c.kind])); + +async function api(path, options = {}) { + const res = await fetch(path, { ...options, headers: { "Content-Type": "application/json", ...(options.headers || {}) } }); + const json = await res.json(); + if (!res.ok) throw new Error(json.error || "Request failed"); + return json; +} + +function setLoading(v) { + state.loading = v; + $("refresh").innerHTML = v ? ' Loading' : "↻ Refresh"; + $("refresh").disabled = v; +} + +async function load(force = false) { + setLoading(true); + try { + state.model = force ? await api("/api/refresh", { method: "POST" }) : await api("/api/state"); + render(); + } catch (e) { $("subtitle").textContent = e.message; } + finally { setLoading(false); } +} + +async function saveFocus() { + setLoading(true); + try { + state.model = await api("/api/focus", { method: "POST", body: JSON.stringify({ mood: $("mood").value, minutes: Number($("minutes").value), busyness: $("busyness").value, focusIntent: $("focusIntent").value }) }); + render(); + } catch (e) { $("subtitle").textContent = e.message; } + finally { setLoading(false); } +} + +function switchTab(tab) { + state.tab = tab; + document.querySelectorAll(".tab").forEach((el) => el.classList.toggle("active", el.dataset.tab === tab)); + document.querySelectorAll(".view").forEach((el) => el.classList.toggle("active", el.dataset.view === tab)); + if (tab === "manage" && !state.discover && !state.discoverLoading) loadDiscover(false); + if (tab === "manage") renderManage(); +} + +function render() { + const m = state.model; if (!m) return; + $("subtitle").innerHTML = "Updated " + new Date(m.generatedAt).toLocaleTimeString() + (m.currentLogin ? " · @" + esc(m.currentLogin) : "") + " · " + m.summary.repoCount + " repos"; + $("mood").value = m.preferences.mood; + $("minutes").value = String(m.preferences.minutes); + $("busyness").value = m.preferences.busyness; + $("focusIntent").value = m.preferences.focusIntent || "balanced"; + $("workCount").textContent = m.focusItems.length; + $("repoCount").textContent = m.repos.length; + $("cleanupCount").textContent = (m.sessionInventory || []).length; + $("errorCount").textContent = m.errors.length; + renderRepoFilter(m.repos); + renderOnboarding(); + renderStats(m.summary); + renderPlan(m); + renderChips(); + renderWork(); + renderRepos(); + renderCleanup(); + renderErrors(m.errors); + if (state.tab === "manage") renderManage(); +} + +function discoverItems() { + if (!state.discover) return []; + const repos = (state.discover.repos || []).map((r) => ({ ...r, source: "github" })); + const projects = (state.discover.projects || []).map((r) => ({ ...r, source: "local" })); + const seen = new Set(); + const items = []; + for (const item of [...projects, ...repos]) { + const key = (item.slug || "").toLowerCase(); + if (!key || seen.has(key)) continue; + seen.add(key); + items.push(item); + } + return items; +} + +function encodedRepo(item) { + return JSON.stringify({ slug: item.slug, path: item.path || null }); +} + +function renderOnboarding() { + const panel = $("onboardingPanel"); + const m = state.model; if (!m || m.onboarded) { panel.innerHTML = ""; return; } + const items = discoverItems().slice(0, 12); + const picks = items.length ? '
' + items.map((r, i) => { + const id = "onboardPick" + i; + const value = encodedRepo(r); + return ''; + }).join("") + '
' : '
Discover repositories and local projects to start picking what this hub should track.
'; + panel.innerHTML = '
Set up your Work Hub
Pick GitHub repositories or local projects to track. Your choices stay local under ~/.copilot/extensions/work-hub/artifacts.
' + picks + '
'; + $("onboardDiscover").addEventListener("click", () => loadDiscover(true)); + $("onboardManage").addEventListener("click", () => switchTab("manage")); + $("onboardTrack").addEventListener("click", trackSelectedOnboarding); + panel.querySelectorAll("[data-onboard-pick]").forEach((el) => el.addEventListener("change", () => { + if (el.checked) state.onboarding.selected.add(el.dataset.onboardPick); + else state.onboarding.selected.delete(el.dataset.onboardPick); + renderOnboarding(); + })); +} + +function renderStats(s) { + const cards = [ + { v: s.repoCount, l: "repos", tab: "repos" }, + { v: s.needsHumanPrCount, l: "PRs need review", cls: s.needsHumanPrCount ? "alert" : "", chip: "needs-review" }, + { v: s.humanIssueCount, l: "human issues", cls: s.humanIssueCount ? "warn" : "", chip: "human" }, + { v: s.openPrCount, l: "open PRs", chip: "open-pr" }, + { v: s.openIssueCount, l: "open issues", chip: "open-issue" }, + { v: s.staleReleaseCount, l: "stale releases", cls: s.staleReleaseCount ? "warn" : "", chip: "stale-release" }, + { v: s.failedDeployCount, l: "failed deploys", cls: s.failedDeployCount ? "alert" : "", chip: "failing-deploy" }, + { v: s.activeSessionCount, l: "recent sessions", chip: "active-session" }, + ]; + $("stats").innerHTML = cards.map((c, i) => '
' + esc(c.v) + '' + esc(c.l) + '
').join(""); + $("stats").querySelectorAll(".stat").forEach((el) => el.addEventListener("click", () => { + const c = cards[Number(el.dataset.i)]; + if (c.tab) { switchTab(c.tab); return; } + if (c.chip) { state.filters.chips = new Set([c.chip]); renderChips(); renderWork(); switchTab("work"); } + })); +} + +function renderPlan(m) { + const total = m.recommendations.reduce((a, r) => a + r.plannedMinutes, 0); + const intentLabels = { balanced: "balanced priorities", prs: "PRs and reviews", "new-code": "new code", "issue-triage": "issue triage", maintenance: "maintenance" }; + const intent = intentLabels[m.preferences.focusIntent || "balanced"] || "balanced priorities"; + $("planSummary").innerHTML = m.recommendations.length + ? "Given you're " + esc(m.preferences.mood) + " with " + esc(m.preferences.minutes) + " min (" + esc(m.preferences.busyness) + ") and want " + esc(intent) + ", here's what to do and how (~" + total + " min):" + : "No focus items right now — you're all caught up. 🎉"; + $("focusList").innerHTML = m.recommendations.length + ? m.recommendations.map((it, i) => itemHtml(it, { rank: i + 1, planned: it.plannedMinutes })).join("") + : '
Nothing needs your attention. Enjoy the calm.
'; + wireRepoLinks($("focusList")); + wireItemCards($("focusList")); +} + +function wireRepoLinks(root) { + root.querySelectorAll(".repo-link[data-detail]").forEach((el) => el.addEventListener("click", (e) => { e.stopPropagation(); openRepoDetail(el.dataset.detail); })); +} + +function itemHtml(it, opts = {}) { + const badges = (it.tags || []).map((t) => '' + esc(t.replace(/-/g, " ")) + '').join(""); + const rank = opts.rank ? '#' + opts.rank + '' : ""; + const right = opts.planned ? '' + esc(opts.planned) + ' min' : '' + esc(it.minutes) + ' min'; + const link = it.url ? '
' + esc(it.title) + '' : esc(it.title); + const actionable = (it.kind === "pr" || it.kind === "issue") && it.number; + const jumpable = it.kind === "session" && it.sessionId; + const attrs = actionable ? ' class="card item actionable kind-' + esc(it.kind) + '" data-item-repo="' + esc(it.repo) + '" data-item-type="' + esc(it.kind) + '" data-item-number="' + esc(it.number) + '"' : ' class="card item kind-' + esc(it.kind) + '"'; + const guidance = opts.rank && (it.what || it.how) ? '
' + (it.what ? '
What: ' + esc(it.what) + '
' : "") + (it.how ? '
How: ' + esc(it.how) + '
' : "") + '
' : ""; + return '' + + '
' + esc(it.kind) + '' + link + '
' + rank + right + '
' + + '
· ' + esc(it.detail) + '
' + + (badges ? '
' + badges + '
' : "") + + (it.reasons && it.reasons.length ? '
Why now: ' + esc(it.reasons.join(", ")) + (opts.rank ? '' : ' · score ' + esc(it.score)) + '
' : "") + + guidance + + (actionable ? '
Click to view & act →
' : "") + + (jumpable ? '
' : "") + + ''; +} + +function wireItemCards(root) { + root.querySelectorAll(".item.actionable").forEach((el) => el.addEventListener("click", (e) => { + if (e.target.closest("a, .repo-link")) return; + openItemDetail(el.dataset.itemRepo, el.dataset.itemType, el.dataset.itemNumber); + })); + root.querySelectorAll(".jump-btn").forEach((el) => el.addEventListener("click", (e) => { e.stopPropagation(); jumpToSession(el); })); +} + +async function jumpToSession(btn) { + const original = btn.textContent; + btn.disabled = true; btn.textContent = "Jumping…"; + try { + const res = await api("/api/session/jump", { method: "POST", body: JSON.stringify({ sessionId: btn.dataset.jump, repo: btn.dataset.jumpRepo, branch: btn.dataset.jumpBranch }) }); + btn.textContent = "✓ " + (res.message || "Requested"); + } catch (e) { + btn.textContent = "⚠ " + e.message; btn.disabled = false; + setTimeout(() => { btn.textContent = original; }, 3000); + } +} + +function renderRepoFilter(repos) { + const cur = state.filters.repo; + $("repoFilter").innerHTML = '' + repos.map((r) => '').join(""); + $("repoFilter").value = cur; +} + +function renderChips() { + $("chips").innerHTML = CHIP_DEFS.map((c) => '').join("") + + (state.filters.chips.size ? '' : ""); + $("chips").querySelectorAll(".chip").forEach((el) => el.addEventListener("click", () => { + const id = el.dataset.chip; + if (id === "__clear") state.filters.chips.clear(); + else if (state.filters.chips.has(id)) state.filters.chips.delete(id); + else state.filters.chips.add(id); + renderChips(); renderWork(); + })); +} + +function renderWork() { + const m = state.model; if (!m) return; + const f = state.filters; + let items = m.focusItems.slice(); + if (f.repo) items = items.filter((it) => it.repo === f.repo); + if (f.text) { const q = f.text.toLowerCase(); items = items.filter((it) => (it.title + " " + it.repo + " " + it.detail).toLowerCase().includes(q)); } + if (f.chips.size) { + const kindChips = [...f.chips].filter((c) => CHIP_KINDS[c]).map((c) => CHIP_KINDS[c]); + const tagChips = [...f.chips].filter((c) => !CHIP_KINDS[c]); + if (kindChips.length) items = items.filter((it) => kindChips.includes(it.kind)); + if (tagChips.length) items = items.filter((it) => tagChips.every((c) => (it.tags || []).includes(c))); + } + if (f.sort === "recent") items.sort((a, b) => (a.updatedAgeDays ?? 999) - (b.updatedAgeDays ?? 999)); + else if (f.sort === "repo") items.sort((a, b) => a.repo.localeCompare(b.repo) || b.score - a.score); + else items.sort((a, b) => b.score - a.score); + $("workList").innerHTML = items.length ? items.map((it) => itemHtml(it)).join("") : '
No work matches these filters.
'; + wireRepoLinks($("workList")); + wireItemCards($("workList")); +} + +const CLEANUP_BUCKETS = [ + { id: "fresh", label: "Fresh (<2d)" }, + { id: "aging", label: "Aging (2–7d)" }, + { id: "stale", label: "Stale (7–30d)" }, + { id: "ancient", label: "Ancient (30d+)" }, + { id: "orphaned", label: "Archived (worktree gone)" }, +]; + +function cleanupInventory() { + const m = state.model; if (!m) return []; + return (m.sessionInventory || []).slice(); +} + +function cleanupFiltered() { + const c = state.cleanup; + let items = cleanupInventory(); + if (c.repo) items = items.filter((s) => s.repository === c.repo); + if (c.text) { const q = c.text.toLowerCase(); items = items.filter((s) => (s.summary + " " + s.repository + " " + s.branch + " " + s.cwd).toLowerCase().includes(q)); } + if (c.buckets.size) items = items.filter((s) => c.buckets.has(s.orphaned ? "orphaned" : s.bucket) || (c.buckets.has("orphaned") && s.orphaned)); + if (c.sort === "newest") items.sort((a, b) => (a.ageDays ?? 1e9) - (b.ageDays ?? 1e9)); + else if (c.sort === "repo") items.sort((a, b) => a.repository.localeCompare(b.repository) || (b.ageDays ?? 0) - (a.ageDays ?? 0)); + else items.sort((a, b) => (b.ageDays ?? -1) - (a.ageDays ?? -1)); + return items; +} + +function renderCleanup() { + const m = state.model; if (!m) return; + const all = cleanupInventory(); + // repo filter options + const repos = [...new Set(all.map((s) => s.repository))].sort(); + const sel = state.cleanup.repo; + $("cleanupRepo").innerHTML = '' + repos.map((r) => '').join(""); + // stats + const s = m.summary; + const orphaned = all.filter((x) => x.orphaned).length; + const ancient = all.filter((x) => x.bucket === "ancient").length; + const cards = [ + { v: all.length, l: "total sessions" }, + { v: s.staleSessionCount ?? 0, l: "stale or older", cls: (s.staleSessionCount ? "warn" : "") }, + { v: ancient, l: "30d+ ancient", cls: ancient ? "warn" : "" }, + { v: orphaned, l: "archived (worktree gone)", cls: orphaned ? "alert" : "" }, + ]; + $("cleanupStats").innerHTML = cards.map((c) => '
' + esc(c.v) + '' + esc(c.l) + '
').join(""); + // bucket chips + const cnt = (id) => all.filter((x) => id === "orphaned" ? x.orphaned : x.bucket === id).length; + $("cleanupChips").innerHTML = CLEANUP_BUCKETS.map((b) => '').join("") + + (state.cleanup.buckets.size ? '' : ""); + $("cleanupChips").querySelectorAll(".chip").forEach((el) => el.addEventListener("click", () => { + const id = el.dataset.cbucket; + if (id === "__clear") state.cleanup.buckets.clear(); + else if (state.cleanup.buckets.has(id)) state.cleanup.buckets.delete(id); + else state.cleanup.buckets.add(id); + renderCleanup(); + })); + // prune stale selections + const validIds = new Set(all.map((x) => x.id)); + for (const id of [...state.cleanup.selected]) if (!validIds.has(id)) state.cleanup.selected.delete(id); + // list + const items = cleanupFiltered(); + $("cleanupList").innerHTML = items.length ? items.map(cleanupRowHtml).join("") : '
No sessions match these filters. 🎉
'; + wireCleanupRows(); + // select-all reflects shown selection + const shownIds = items.map((x) => x.id); + $("cleanupAll").checked = shownIds.length > 0 && shownIds.every((id) => state.cleanup.selected.has(id)); + updateCleanupBar(); +} + +function cleanupRowHtml(sn) { + const checked = state.cleanup.selected.has(sn.id) ? " checked" : ""; + const archived = sn.orphaned; + const badge = archived ? '📦 archived' : '' + esc(sn.bucket) + ''; + const where = archived ? "worktree removed" : (sn.isWorktree ? "worktree" : "main checkout"); + const openBtn = archived + ? '' + : ''; + const menu = '
' + + '' + + '
' + + (archived ? '' : '') + + '' + + (sn.branch ? '' : '') + + '
' + + '
'; + return '
' + + '' + + '
' + + '
' + esc(sn.summary) + '
' + + '
' + esc(sn.repository) + (sn.branch ? ' · ' + esc(sn.branch) + '' : "") + ' · ' + where + ' · last active ' + esc(sn.ageLabel) + ' ago
' + + '
' + + '
' + badge + openBtn + menu + '
' + + '
'; +} + +function closeCleanupMenus() { + document.querySelectorAll(".crow-menu.open").forEach((el) => el.classList.remove("open")); +} + +function wireCleanupRows() { + $("cleanupList").querySelectorAll("[data-cselect]").forEach((el) => el.addEventListener("change", () => { + const id = el.dataset.cselect; + if (el.checked) state.cleanup.selected.add(id); else state.cleanup.selected.delete(id); + el.closest(".cleanup-row").classList.toggle("selected", el.checked); + updateCleanupBar(); + const items = cleanupFiltered(); const shownIds = items.map((x) => x.id); + $("cleanupAll").checked = shownIds.length > 0 && shownIds.every((x) => state.cleanup.selected.has(x)); + })); + const doJump = (el) => { el.dataset.jump = el.dataset.cjump || el.dataset.cjump2; jumpToSession(el); }; + $("cleanupList").querySelectorAll("[data-cjump]").forEach((el) => el.addEventListener("click", () => doJump(el))); + $("cleanupList").querySelectorAll("[data-cjump2]").forEach((el) => el.addEventListener("click", () => { closeCleanupMenus(); doJump(el); })); + $("cleanupList").querySelectorAll("[data-cmenu]").forEach((el) => el.addEventListener("click", (e) => { + e.stopPropagation(); + const menu = $("cleanupList").querySelector('[data-menu-for="' + CSS.escape(el.dataset.cmenu) + '"]'); + const wasOpen = menu.classList.contains("open"); + closeCleanupMenus(); + if (!wasOpen) menu.classList.add("open"); + })); + $("cleanupList").querySelectorAll("[data-cdel]").forEach((el) => el.addEventListener("click", () => { closeCleanupMenus(); deleteOneSession(el.dataset.cdel); })); + $("cleanupList").querySelectorAll("[data-copybranch]").forEach((el) => el.addEventListener("click", () => { + navigator.clipboard?.writeText(el.dataset.copybranch); + el.textContent = "✓ Copied"; setTimeout(() => { el.textContent = "⧉ Copy branch name"; closeCleanupMenus(); }, 900); + })); +} + +async function requestSessionCleanup(list, btn, original) { + btn.disabled = true; btn.innerHTML = ' Requesting…'; + try { + const payload = { sessions: list.map((s) => ({ id: s.id, repo: s.repository, branch: s.branch, summary: s.summary, ageLabel: s.ageLabel, archived: s.orphaned })) }; + const res = await api("/api/session/cleanup", { method: "POST", body: JSON.stringify(payload) }); + btn.innerHTML = "✓ " + (res.message || "Requested"); + list.forEach((s) => state.cleanup.selected.delete(s.id)); + setTimeout(() => { load(true); }, 500); + } catch (e) { + btn.disabled = false; btn.innerHTML = original; + $("cleanupSelInfo").textContent = e.message; + } +} + +function deleteOneSession(id) { + const sn = cleanupInventory().find((s) => s.id === id); + if (!sn) return; + if (!confirm('Clean up this session?\\n\\n' + sn.repository + (sn.branch ? ' · ' + sn.branch : '') + '\\n"' + sn.summary + '"' + (sn.orphaned ? '\\n\\n(Already archived — this removes the leftover record/worktree.)' : ''))) return; + requestSessionCleanup([sn], $("cleanupDelete"), $("cleanupDelete").innerHTML); +} + +function updateCleanupBar() { + const n = state.cleanup.selected.size; + $("cleanupSelInfo").textContent = n + " selected"; + $("cleanupDelete").disabled = n === 0; + $("cleanupDelete").innerHTML = n ? "🗑 Clean up " + n + " selected" : "🗑 Clean up selected"; +} + +async function deleteSelectedSessions() { + const all = cleanupInventory(); + const chosen = all.filter((s) => state.cleanup.selected.has(s.id)); + if (!chosen.length) return; + requestSessionCleanup(chosen, $("cleanupDelete"), $("cleanupDelete").innerHTML); +} + +function renderRepos() { + const m = state.model; if (!m) return; + const f = state.filters; + let repos = m.repos.slice(); + if (f.repoText) { const q = f.repoText.toLowerCase(); repos = repos.filter((r) => (r.slug + " " + (r.description || "") + " " + (r.language || "")).toLowerCase().includes(q)); } + const toneRank = { danger: 0, attention: 1, active: 2, neutral: 3, good: 4, muted: 5 }; + if (f.repoSort === "release") repos.sort((a, b) => (b.releaseAgeDays ?? 1e9) - (a.releaseAgeDays ?? 1e9)); + else if (f.repoSort === "work") repos.sort((a, b) => (b.openPrCount + b.openIssueCount) - (a.openPrCount + a.openIssueCount)); + else if (f.repoSort === "name") repos.sort((a, b) => a.slug.localeCompare(b.slug)); + else repos.sort((a, b) => (toneRank[a.status.tone] ?? 9) - (toneRank[b.status.tone] ?? 9) || b.needsHumanPrCount - a.needsHumanPrCount); + $("repoGrid").innerHTML = repos.map(repoHtml).join(""); + $("repoGrid").querySelectorAll("[data-detail]").forEach((el) => el.addEventListener("click", (e) => { e.stopPropagation(); openRepoDetail(el.dataset.detail); })); + $("repoGrid").querySelectorAll(".expand-btn:not([data-detail])").forEach((el) => el.addEventListener("click", (e) => { e.stopPropagation(); el.closest(".repo-card").classList.toggle("open"); })); + $("repoGrid").querySelectorAll(".repo-card").forEach((el) => el.addEventListener("click", (e) => { if (e.target.closest("a,button")) return; openRepoDetail(el.dataset.repo); })); + wireSubItems($("repoGrid")); +} + +function wireSubItems(root) { + root.querySelectorAll(".actionable-sub").forEach((el) => el.addEventListener("click", (e) => { + if (e.target.closest("a")) return; + e.stopPropagation(); + openItemDetail(el.dataset.openRepo, el.dataset.openType, el.dataset.openNumber); + })); +} + +function repoHtml(r) { + const sub = [ + ...r.prs.map((p) => ({ t: "PR #" + p.number + " " + p.title, u: p.url, m: p.author, type: "pr", n: p.number })), + ...r.issues.map((i) => ({ t: "Issue #" + i.number + " " + i.title, u: i.url, m: i.author, type: "issue", n: i.number })), + ]; + const subHtml = sub.length ? sub.slice(0, 12).map((s) => '
' + esc(s.t) + '' + esc(s.m) + '
').join("") : '
No open PRs or issues.
'; + const local = r.localGit && r.localGit.available ? ((r.localGit.branchLine || "git").replace(/^## /, "") + " · " + (r.localGit.dirtyCount || 0) + " changed") : "no local checkout"; + return '
' + + '
' + esc(r.slug) + '' + (r.isPrivate ? ' private' : "") + '
' + esc(r.description || r.language || r.defaultBranch) + '
' + + '' + esc(r.status.label) + '
' + + '
' + metric(r.openPrCount, "PRs") + metric(r.openIssueCount, "Issues") + metric(r.needsHumanPrCount, "Review") + metric(r.releaseAgeLabel, "Release") + '
' + + '
' + esc(r.status.detail) + '
' + + (r.latestDeploy ? '
🚀 ' + esc(r.latestDeploy.environment) + ' ' + esc(r.latestDeploy.state) + ' ' + esc(ageLabelClient(r.latestDeploy.ageDays)) + ' ago' + (r.deployments.length > 1 ? ' +' + (r.deployments.length - 1) + ' env' : "") + '
' : '
🚀 no deployments
') + + '
🖥 ' + esc(local) + '
' + + '
' + + '' + + (sub.length ? '' : "") + + '
' + + '
' + subHtml + '
' + + '
'; +} + +function ageLabelClient(days) { + if (days === null || days === undefined) return "unknown"; + if (days === 0) return "today"; + if (days === 1) return "1 day"; + if (days < 30) return days + " days"; + const months = Math.floor(days / 30); + if (months < 18) return months + " mo"; + return Math.floor(days / 365) + " yr"; +} + +function metric(v, l) { return '
' + esc(v) + '' + esc(l) + '
'; } + +function renderErrors(errors) { + $("errorList").innerHTML = errors.length ? errors.slice(0, 20).map((e) => '
' + esc(e.repo || e.source || "source") + ': ' + esc(e.message) + '
').join("") : '
All data sources returned successfully.
'; +} + +/* ---- repo detail drawer ---- */ +function openRepoDetail(slug) { + const m = state.model; if (!m) return; + const r = m.repos.find((x) => x.slug === slug); if (!r) return; + const rel = r.latestRelease; + const deployHtml = r.deployments && r.deployments.length + ? r.deployments.map((d) => '
' + (d.url ? '' + esc(d.environment) + '' : '' + esc(d.environment) + '') + '
ref ' + esc(d.ref || "—") + '
' + esc(d.state) + '
' + esc(ageLabelClient(d.ageDays)) + ' ago
').join("") + : '
No deployments found.
'; + const prHtml = r.prs.length ? r.prs.map((p) => '
#' + p.number + ' ' + esc(p.title) + '
' + esc(p.author) + ' · ' + esc(p.reviewDecision) + (p.failingChecks ? ' · ⚠ checks failing' : '') + (p.isDraft ? ' · draft' : '') + ' · View & act →
').join("") : '
No open PRs.
'; + const issueHtml = r.issues.length ? r.issues.map((i) => '
#' + i.number + ' ' + esc(i.title) + '
' + esc(i.author) + ' · ' + i.comments + ' comments' + (i.assignedToJames ? ' · assigned to you' : '') + ' · View & act →
').join("") : '
No open issues.
'; + const g = r.localGit || {}; + const localHtml = g.available + ? '
Branch: ' + esc((g.branchLine || "").replace(/^## /, "") || "?") + '
' + metric(g.dirtyCount || 0, "changed") + metric(g.ahead || 0, "ahead") + metric(g.behind || 0, "behind") + metric(ageLabelClient(g.lastCommitAgeDays), "last commit") + '
' + esc(g.path || "") + '
' + : '
No local checkout detected under ~/Projects.
'; + const sessionHtml = r.activeSessions && r.activeSessions.length + ? r.activeSessions.map((s) => '
' + esc(s.summary) + '
' + esc(s.branch || "?") + ' · updated ' + esc(ageLabelClient(s.ageDays)) + ' ago
').join("") + : '
No recent sessions.
'; + + $("detailDrawer").innerHTML = + '

' + esc(r.slug) + '

' + esc(r.description || r.language || r.defaultBranch) + '
' + + '
' + + '' + esc(r.status.label) + '' + + 'Open on GitHub ↗' + + (r.isPrivate ? 'private' : '') + (r.language ? '' + esc(r.language) + '' : '') + '★ ' + (r.stars || 0) + '' + + '
' + + '
' + esc(r.status.detail) + '
' + + '

Overview

' + metric(r.openPrCount, "Open PRs") + metric(r.openIssueCount, "Open issues") + metric(r.needsHumanPrCount, "Need review") + metric(ageLabelClient(r.pushedAgeDays), "Last push") + '
' + + '

Deployments

' + deployHtml + '
' + + '

Latest release

' + (rel ? '
' + (rel.url ? '' + esc(rel.tagName || rel.name) + '' : '' + esc(rel.tagName || rel.name) + '') + '
' + esc(rel.kind) + ' · ' + esc(ageLabelClient(r.releaseAgeDays)) + ' ago
' : '
No release or tag found.
') + '
' + + '

Open PRs (' + r.prs.length + ')

' + prHtml + '
' + + '

Open issues (' + r.issues.length + ')

' + issueHtml + '
' + + '

Local checkout

' + localHtml + '
' + + '

Recent sessions

' + sessionHtml + '
'; + $("detailOverlay").classList.add("open"); + $("detailClose").addEventListener("click", closeRepoDetail); + wireSubItems($("detailDrawer")); +} + +function closeRepoDetail() { $("detailOverlay").classList.remove("open"); } + +/* ---- item detail + actions ---- */ +let itemCtx = null; + +async function openItemDetail(repo, type, number) { + itemCtx = { repo, type, number }; + $("itemDrawer").innerHTML = '

' + esc(type.toUpperCase()) + ' #' + esc(number) + '

' + esc(repo) + '
'; + $("itemOverlay").classList.add("open"); + $("itemClose").addEventListener("click", closeItemDetail); + try { + const it = await api("/api/item?repo=" + encodeURIComponent(repo) + "&type=" + encodeURIComponent(type) + "&number=" + encodeURIComponent(number)); + renderItemPane(it); + } catch (e) { + $("itemDrawer").innerHTML = '

Could not load

' + esc(e.message) + '
'; + $("itemClose").addEventListener("click", closeItemDetail); + } +} + +function renderItemPane(it) { + const isPr = it.type === "pr"; + const stateLabel = it.state + (it.isDraft ? " · draft" : ""); + const meta = []; + meta.push('' + esc(stateLabel) + ''); + if (isPr) { + meta.push('' + esc(it.reviewDecision) + ''); + if (it.checksTotal) meta.push('' + (it.checksFailing ? it.checksFailing + ' failing' : 'checks ok') + ''); + meta.push('' + esc(it.mergeable) + ''); + } + it.labels.forEach((l) => meta.push('' + esc(l) + '')); + const metrics = isPr + ? '
' + metric('+' + (it.additions ?? 0), "additions") + metric('-' + (it.deletions ?? 0), "deletions") + metric(it.changedFiles ?? 0, "files") + metric(ageLabelClient(it.ageDays), "updated") + '
' + : '
' + metric(it.comments.length, "comments") + metric(it.assignees.length, "assignees") + metric(ageLabelClient(it.ageDays), "updated") + '
'; + const branchLine = isPr ? '
' + esc(it.headRefName) + ' → ' + esc(it.baseRefName) + '
' : ''; + const assignLine = it.assignees.length ? '
Assignees: ' + esc(it.assignees.join(", ")) + '
' : ''; + const bodyHtml = it.body.trim() ? '
' + esc(it.body) + '
' : '
No description.
'; + const commentsHtml = it.comments.length + ? it.comments.map((c) => '
' + esc(c.author || "unknown") + ' · ' + esc(ageLabelClient(c.ageDays)) + ' ago
' + esc(c.body) + '
').join("") + : '
No comments yet.
'; + + const actions = []; + actions.push(''); + if (isPr) { + if (it.isDraft) actions.push(''); + actions.push(''); + actions.push(''); + actions.push(''); + actions.push(''); + } else { + if (it.assignees.map((a) => a.toLowerCase()).includes((state.model.currentLogin || "").toLowerCase())) actions.push(''); + else actions.push(''); + } + if (it.state && it.state.toUpperCase() === "OPEN") actions.push(''); + else actions.push(''); + + $("itemDrawer").innerHTML = + '

' + esc(it.title) + '

' + esc(it.repo) + ' · ' + esc(it.type.toUpperCase()) + ' #' + it.number + ' · by ' + esc(it.author || "unknown") + '
' + + '
' + meta.join("") + '
' + + branchLine + assignLine + + '
' + metrics + '
' + + '

Description

' + bodyHtml + '
' + + '

Work on this

' + (isPr ? "" : '') + '
Plan proposes an approach; Implement starts coding' + (isPr ? "" : "; Refine spec sharpens requirements; Cloud assigns the issue to a remote coding session") + '. New session in the ' + esc(it.repo) + ' project.
' + + '

Actions

' + actions.join("") + '
' + + '' + + '
' + + '

Recent comments (' + it.comments.length + ')

' + commentsHtml + '
'; + + $("itemClose").addEventListener("click", closeItemDetail); + $("itemDrawer").querySelectorAll("[data-act]").forEach((el) => el.addEventListener("click", () => runAct(el.dataset.act, it, el))); +} + +async function runAct(act, it, btn) { + const status = $("actStatus"); + if (act === "open-gh") { window.open(it.url, "_blank", "noopener,noreferrer"); return; } + if (act === "create-session") { + const mode = btn && ["implement", "spec", "cloud"].includes(btn.dataset.mode) ? btn.dataset.mode : "plan"; + const label = mode === "implement" ? "build" : mode === "spec" ? "spec-refinement" : mode === "cloud" ? "cloud" : "planning"; + status.className = "act-status"; status.textContent = "Requesting a " + label + " session…"; + $("itemDrawer").querySelectorAll("[data-act]").forEach((b) => b.disabled = true); + try { + const res = await api("/api/item/session", { method: "POST", body: JSON.stringify({ repo: it.repo, type: it.type, number: it.number, title: it.title, mode }) }); + status.className = "act-status ok"; status.textContent = res.message || "Session requested — check your chat."; + } catch (e) { + status.className = "act-status err"; status.textContent = e.message; + } finally { + $("itemDrawer").querySelectorAll("[data-act]").forEach((b) => b.disabled = false); + } + return; + } + if ((act === "merge" || act === "close") && !confirm("Are you sure you want to " + act + " " + it.type.toUpperCase() + " #" + it.number + "?")) return; + const body = act === "comment" ? ($("commentBox") ? $("commentBox").value.trim() : "") : ""; + if (act === "comment" && !body) { status.className = "act-status err"; status.textContent = "Enter a comment first."; return; } + status.className = "act-status"; status.textContent = "Working…"; + $("itemDrawer").querySelectorAll("[data-act]").forEach((b) => b.disabled = true); + try { + const res = await api("/api/item/action", { method: "POST", body: JSON.stringify({ repo: it.repo, type: it.type, number: it.number, action: act, body }) }); + status.className = "act-status ok"; status.textContent = (res.output || (act + " succeeded.")) + " · refreshing…"; + const fresh = await api("/api/item?repo=" + encodeURIComponent(it.repo) + "&type=" + encodeURIComponent(it.type) + "&number=" + encodeURIComponent(it.number)); + renderItemPane(fresh); + await load(true); + const s2 = $("actStatus"); if (s2) { s2.className = "act-status ok"; s2.textContent = res.output || (act + " succeeded."); } + } catch (e) { + status.className = "act-status err"; status.textContent = e.message; + $("itemDrawer").querySelectorAll("[data-act]").forEach((b) => b.disabled = false); + } +} + +function closeItemDetail() { $("itemOverlay").classList.remove("open"); itemCtx = null; } + +/* ---- manage ---- */ +async function loadDiscover(force) { + state.discoverLoading = true; + $("discoverGrid").innerHTML = '
'; + try { state.discover = await api("/api/available-repos" + (force ? "?force=1" : "")); } + catch (e) { $("discoverGrid").innerHTML = '
' + esc(e.message) + '
'; } + finally { state.discoverLoading = false; renderManage(); renderOnboarding(); } +} + +function renderManage() { + const m = state.model; if (!m) return; + const tracked = m.repos; + $("trackedCount").textContent = tracked.length; + $("trackedList").innerHTML = tracked.map((r) => '
' + esc(r.slug) + '' + (r.path ? ' local' : "") + '
' + esc(r.status ? r.status.label : "") + ' · ' + r.openPrCount + ' PRs · ' + r.openIssueCount + ' issues
').join("") || '
No repos tracked yet.
'; + $("trackedList").querySelectorAll("[data-remove]").forEach((el) => el.addEventListener("click", () => removeRepo(el.dataset.remove))); + + if (!state.discover) { if (!state.discoverLoading) $("discoverGrid").innerHTML = '
Click “Reload my repos”.
'; return; } + const trackedSet = new Set(tracked.map((r) => r.slug.toLowerCase())); + const q = state.filters.discoverText.toLowerCase(); + const repos = discoverItems().filter((r) => !q || (r.slug + " " + (r.description || "") + " " + (r.path || "")).toLowerCase().includes(q)); + $("discoverGrid").innerHTML = repos.slice(0, 120).map((r) => { + const isTracked = trackedSet.has(r.slug.toLowerCase()); + const payload = esc(encodedRepo(r)); + return '
' + esc(r.slug) + '' + + (isTracked ? 'tracked' : '') + '
' + + '
' + esc(r.description || "No description") + '
' + + '
' + (r.source === "local" ? "local project · " + esc(r.path || "") : (r.isPrivate ? "private · " : "") + (r.isFork ? "fork · " : "") + "★ " + (r.stars || 0) + " · pushed " + esc(r.pushedAgeDays === null ? "?" : r.pushedAgeDays + "d ago")) + '
'; + }).join("") || '
No repositories match.
'; + $("discoverGrid").querySelectorAll("[data-add-repo]").forEach((el) => el.addEventListener("click", () => addRepo(JSON.parse(el.dataset.addRepo)))); +} + +async function trackSelectedOnboarding() { + const repos = [...state.onboarding.selected].map((value) => JSON.parse(value)); + if (!repos.length) return; + try { + await api("/api/repos/set", { method: "POST", body: JSON.stringify({ repos, onboarded: true }) }); + state.onboarding.selected.clear(); + await load(true); + } catch (e) { alert(e.message); } +} + +async function addRepo(slug) { + const repo = typeof slug === "string" ? { slug } : slug; + try { await api("/api/repos/add", { method: "POST", body: JSON.stringify({ repos: [repo] }) }); await load(true); switchTab("manage"); } + catch (e) { alert(e.message); } +} +async function removeRepo(slug) { + try { await api("/api/repos/remove", { method: "POST", body: JSON.stringify({ slug }) }); await load(true); switchTab("manage"); } + catch (e) { alert(e.message); } +} + +/* ---- wiring ---- */ +$("refresh").addEventListener("click", () => load(true)); +["mood", "minutes", "busyness", "focusIntent"].forEach((id) => $(id).addEventListener("change", saveFocus)); +document.querySelectorAll(".tab").forEach((el) => el.addEventListener("click", () => switchTab(el.dataset.tab))); +$("search").addEventListener("input", (e) => { state.filters.text = e.target.value; renderWork(); }); +$("repoFilter").addEventListener("change", (e) => { state.filters.repo = e.target.value; renderWork(); }); +$("sort").addEventListener("change", (e) => { state.filters.sort = e.target.value; renderWork(); }); +$("repoSearch").addEventListener("input", (e) => { state.filters.repoText = e.target.value; renderRepos(); }); +$("repoSort").addEventListener("change", (e) => { state.filters.repoSort = e.target.value; renderRepos(); }); +$("cleanupSearch").addEventListener("input", (e) => { state.cleanup.text = e.target.value; renderCleanup(); }); +$("cleanupRepo").addEventListener("change", (e) => { state.cleanup.repo = e.target.value; renderCleanup(); }); +$("cleanupSort").addEventListener("change", (e) => { state.cleanup.sort = e.target.value; renderCleanup(); }); +$("cleanupAll").addEventListener("change", (e) => { + const items = cleanupFiltered(); + if (e.target.checked) items.forEach((s) => state.cleanup.selected.add(s.id)); + else items.forEach((s) => state.cleanup.selected.delete(s.id)); + renderCleanup(); +}); +$("cleanupSelectStale").addEventListener("click", () => { + cleanupInventory().forEach((s) => { if (s.orphaned || s.bucket === "stale" || s.bucket === "ancient") state.cleanup.selected.add(s.id); }); + renderCleanup(); +}); +$("cleanupDelete").addEventListener("click", deleteSelectedSessions); +$("discoverSearch").addEventListener("input", (e) => { state.filters.discoverText = e.target.value; renderManage(); }); +$("reloadDiscover").addEventListener("click", () => loadDiscover(true)); +$("addManual").addEventListener("click", () => { const v = $("manualRepo").value.trim(); if (v) { $("manualRepo").value = ""; addRepo(v); } }); +$("manualRepo").addEventListener("keydown", (e) => { if (e.key === "Enter") $("addManual").click(); }); +$("detailBg").addEventListener("click", closeRepoDetail); +$("itemBg").addEventListener("click", closeItemDetail); +document.addEventListener("keydown", (e) => { if (e.key === "Escape") { closeItemDetail(); closeRepoDetail(); closeCleanupMenus(); } }); +document.addEventListener("click", (e) => { if (!e.target.closest(".crow-manage")) closeCleanupMenus(); }); + +const events = new EventSource("/events"); +events.addEventListener("state", () => load(false)); +load(false); +`; +}