mirror of
https://github.com/block/buzz.git
synced 2026-11-14 05:12:27 +00:00
## Summary - inject bounded project-home identity and repository context into managed agent sessions - add project-aware CLI flows for creating projects, repositories, issues, and related channels - match project homes through the existing relay query surface, then filter channel metadata client-side This is Part 1 of the channel-first Projects stack. Part 2 contains project creation and model foundations. ## Testing - `cargo fmt --all -- --check` - `cargo clippy -p buzz-cli -p buzz-acp --all-targets -- -D warnings` - `cargo test -p buzz-cli -p buzz-acp` — 1,184 tests passed, 1 doc test ignored - full pre-push gate passed ## Post-Deploy Monitoring & Validation - validate project-home agent context and project-aware CLI commands against a staging relay - healthy signals: project context matches the active channel, explicit repo coordinates remain stable, and normal channels receive no project block - failure signals: cross-channel project context, duplicate project creation, or commands targeting an unrelated repository; mitigate by reverting this PR --------- Signed-off-by: Thomas Petersen <thomasp@squareup.com> Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz> Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
89 lines
2.5 KiB
TypeScript
89 lines
2.5 KiB
TypeScript
import type {
|
|
Project,
|
|
ProjectActivitySummary,
|
|
ProjectIssueListItem,
|
|
ProjectPullRequestListItem,
|
|
ProjectRepoSnapshot,
|
|
} from "@/features/projects/hooks";
|
|
|
|
const WEEK_SECONDS = 7 * 24 * 60 * 60;
|
|
|
|
export type ProjectsActivityDigest = {
|
|
highlights: string[];
|
|
prefix: string;
|
|
suffix: string;
|
|
};
|
|
|
|
function plural(count: number, singular: string, pluralForm = `${singular}s`) {
|
|
return `${count} ${count === 1 ? singular : pluralForm}`;
|
|
}
|
|
|
|
/** Builds a short, deterministic sentence from the currently loaded activity. */
|
|
export function buildProjectsActivityDigest({
|
|
issues,
|
|
nowSeconds,
|
|
projects,
|
|
pullRequests,
|
|
snapshots,
|
|
summaries,
|
|
}: {
|
|
issues: ProjectIssueListItem[];
|
|
nowSeconds: number;
|
|
projects: Project[];
|
|
pullRequests: ProjectPullRequestListItem[];
|
|
snapshots?: Record<string, ProjectRepoSnapshot>;
|
|
summaries?: Record<string, ProjectActivitySummary>;
|
|
}): ProjectsActivityDigest {
|
|
const since = nowSeconds - WEEK_SECONDS;
|
|
const activeProjectIds = new Set<string>();
|
|
let commitCount = 0;
|
|
for (const [projectId, snapshot] of Object.entries(snapshots ?? {})) {
|
|
const recent = snapshot.commits.filter(
|
|
(commit) => commit.timestamp >= since,
|
|
).length;
|
|
commitCount += recent;
|
|
if (recent > 0) activeProjectIds.add(projectId);
|
|
}
|
|
const taskCount = issues.filter(({ issue, project }) => {
|
|
const recent = issue.createdAt >= since;
|
|
if (recent) activeProjectIds.add(project.id);
|
|
return recent;
|
|
}).length;
|
|
const reviewCount = pullRequests.filter(({ project, pullRequest }) => {
|
|
const recent = pullRequest.createdAt >= since;
|
|
if (recent) activeProjectIds.add(project.id);
|
|
return recent;
|
|
}).length;
|
|
const highlights = [
|
|
commitCount > 0 ? `${plural(commitCount, "new commit")}` : null,
|
|
taskCount > 0 ? `${plural(taskCount, "task")} opened` : null,
|
|
reviewCount > 0 ? `${plural(reviewCount, "review")} opened` : null,
|
|
].filter((value): value is string => value !== null);
|
|
|
|
if (highlights.length > 0) {
|
|
highlights.push(`${plural(activeProjectIds.size, "active project")}`);
|
|
return {
|
|
highlights,
|
|
prefix: "This week:",
|
|
suffix: ".",
|
|
};
|
|
}
|
|
|
|
const totals = Object.values(summaries ?? {}).reduce(
|
|
(result, summary) => ({
|
|
reviews: result.reviews + summary.prCount,
|
|
tasks: result.tasks + summary.issueCount,
|
|
}),
|
|
{ reviews: 0, tasks: 0 },
|
|
);
|
|
return {
|
|
highlights: [
|
|
plural(projects.length, "project"),
|
|
plural(totals.tasks, "task"),
|
|
plural(totals.reviews, "review"),
|
|
],
|
|
prefix: "Currently tracking",
|
|
suffix: ".",
|
|
};
|
|
}
|