mirror of
https://github.com/block/buzz.git
synced 2026-11-08 18:31:56 +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>
63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
import * as React from "react";
|
|
|
|
import { homeRepositoriesToBind } from "@/features/projects/lib/projectCollection";
|
|
import type { Project } from "@/features/projects/projectModels";
|
|
import { useAttachProjectRepositoryMutation } from "@/features/projects/useAttachProjectRepository";
|
|
import { relayClient } from "@/shared/api/relayClient";
|
|
import { KIND_PROJECT_ANNOUNCEMENT } from "@/shared/constants/kinds";
|
|
import { normalizePubkey } from "@/shared/lib/pubkey";
|
|
|
|
/**
|
|
* When the signed-in user owns this project, bind absorbed home-channel
|
|
* repositories onto the `kind:30621` so Overview, other clients, and NIP-MP
|
|
* agree. Agents can announce a repo with `--channel` but cannot edit the
|
|
* owner's project event.
|
|
*/
|
|
export function useHealProjectHomeRepositories(
|
|
project: Project,
|
|
identityPubkey?: string,
|
|
) {
|
|
const attachMutation = useAttachProjectRepositoryMutation();
|
|
const attemptedRef = React.useRef(new Set<string>());
|
|
const mutateAsync = attachMutation.mutateAsync;
|
|
|
|
React.useEffect(() => {
|
|
if (!identityPubkey) return;
|
|
if (normalizePubkey(identityPubkey) !== normalizePubkey(project.owner)) {
|
|
return;
|
|
}
|
|
if (project.repositories.length === 0) return;
|
|
|
|
let cancelled = false;
|
|
void (async () => {
|
|
const liveHeads = await relayClient.fetchEvents({
|
|
authors: [project.owner],
|
|
kinds: [KIND_PROJECT_ANNOUNCEMENT],
|
|
limit: 1,
|
|
"#d": [project.dtag],
|
|
});
|
|
if (cancelled) return;
|
|
const liveHead = liveHeads[0];
|
|
if (!liveHead) return;
|
|
const signedAddresses = liveHead.tags
|
|
.filter((tag) => tag[0] === "a" && tag[1])
|
|
.map((tag) => tag[1] as string);
|
|
const pending = homeRepositoriesToBind(project, signedAddresses);
|
|
for (const repository of pending) {
|
|
const key = `${project.projectAddress}:${repository.repoAddress}`;
|
|
if (attemptedRef.current.has(key)) continue;
|
|
attemptedRef.current.add(key);
|
|
try {
|
|
await mutateAsync({ project, repository });
|
|
} catch {
|
|
// Already bound, raced, or not owner-writable this session.
|
|
}
|
|
}
|
|
})();
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [identityPubkey, mutateAsync, project]);
|
|
}
|