Files
buzz/desktop/src/features/projects/useProjectRepositorySnapshots.ts
thomaspblock de188ebf06 feat(projects): add agent and CLI project-home support (#6590)
## 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>
2026-08-26 12:09:06 -07:00

68 lines
1.9 KiB
TypeScript

import { useQueries } from "@tanstack/react-query";
import type {
ProjectRepoSnapshot,
Repository,
} from "@/features/projects/hooks";
import { fetchRepoState } from "@/features/projects/hooks";
import { resolveProjectDefaultBranch } from "@/features/projects/lib/projectBranches";
import { getProjectRepoSnapshot } from "@/shared/api/projectGit";
export type ProjectRepositorySnapshotResult = {
error: unknown;
isLoading: boolean;
repository: Repository;
snapshot: ProjectRepoSnapshot | null;
};
/** Loads each project repository independently so one failure stays partial. */
export function useProjectRepositorySnapshots(
repositories: Repository[],
enabled = true,
): ProjectRepositorySnapshotResult[] {
const queries = useQueries({
queries: repositories.map((repository) => ({
enabled: Boolean(enabled && repository.cloneUrls[0]),
queryFn: async () => {
const cloneUrl = repository.cloneUrls[0];
if (!cloneUrl) return null;
const repoState = await fetchRepoState(repository);
const defaultBranch = resolveProjectDefaultBranch(
repository.defaultBranch,
repoState,
);
return getProjectRepoSnapshot({
baseBranch: defaultBranch,
cloneUrl,
defaultBranch,
});
},
queryKey: [
"project",
repository.id,
"repo-snapshot",
repository.defaultBranch,
"none",
"none",
"no-tag",
"no-tag-commit",
],
retry: 1,
staleTime: 30_000,
})),
});
return repositories.map((repository, index) => {
const query = queries[index];
return {
error:
enabled && !repository.cloneUrls[0]
? new Error("Repository not found on the relay.")
: query?.error,
isLoading: query?.isLoading ?? false,
repository,
snapshot: query?.data ?? null,
};
});
}