diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index cf3195c2..b0153209 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,28 +1,17 @@ # Contributing -Thanks for contributing to Claude Agent Teams UI. +Thanks for contributing to Claude Agent Teams UI! -## Project Philosophy & Scope +## Before You Start -claude-devtools exists to make the invisible parts of Claude Code visible — the token flows, context injections, tool executions, and session dynamics that are otherwise hidden behind the CLI. It is not a general-purpose dashboard or an IDE. +For big features and major changes, please discuss them in our [Discord](https://discord.gg/RgBHMBsn) first so we can figure out the best approach together and avoid conflicts. -Our priorities: - -1. **Parity with Claude Code** — When Claude Code ships new capabilities (agent teams, context tracking, new tool types), we adopt them quickly so users always have full visibility. -2. **Context engineering insight** — Features that help users understand *what* is consuming their context window, *how* tokens flow through a session, and *where* to optimize. If it doesn't help someone make better decisions about their Claude Code usage, it probably doesn't belong here. -3. **Stability over novelty** — A reliable, fast tool for professional workflows. We'd rather do fewer things well than many things poorly. - -**What we generally do not accept:** -- Large custom features that don't directly serve context visibility or Claude Code parity. -- Speculative features that add maintenance burden without solving a concrete problem users face today. -- PRs that significantly expand scope without prior discussion in an Issue. - -If you're considering a non-trivial contribution, **open an Issue first** to check alignment with the current roadmap. This saves everyone time and keeps the project focused. +Small fixes, bug reports, and minor improvements are always welcome -- just open a PR. ## Prerequisites - Node.js 20+ - pnpm 10+ -- macOS or Windows +- macOS, Windows, or Linux ## Setup ```bash @@ -39,12 +28,16 @@ pnpm test pnpm build ``` +Or all at once: +```bash +pnpm check +``` + ## Pull Request Guidelines -- Keep changes focused and small — one purpose per PR. +- Keep changes focused and small -- one purpose per PR. - Add/adjust tests for behavior changes. - Update docs when changing public behavior or setup. - Use clear PR titles and include a short validation checklist. -- **Large changes (new features, new dependencies, large data additions) must have a discussion in an Issue first.** Do not open a large PR without prior agreement on the approach. - Avoid committing large hardcoded data blobs. If data can be fetched at runtime or generated at build time, prefer that approach. ## AI-Assisted Contributions @@ -52,15 +45,14 @@ pnpm build AI coding tools are welcome, but **you are responsible for what you submit**: - **Review before submitting.** Read every line of AI-generated code and understand what it does. Do not submit raw, unreviewed AI output. -- **Do not commit AI workflow artifacts.** Planning documents, session logs, step-by-step plans, or other outputs from AI tools (e.g. `docs/plans/`, `.speckit/`, etc.) do not belong in the repository. -- **Test it yourself.** AI-generated code must be manually verified — run the app, confirm the feature works, check edge cases. +- **Do not commit AI workflow artifacts.** Planning documents, session logs, step-by-step plans, or other outputs from AI tools do not belong in the repository. +- **Test it yourself.** AI-generated code must be manually verified -- run the app, confirm the feature works, check edge cases. - **Keep it intentional.** Every line in your PR should exist for a reason you can explain. If you can't explain why a piece of code is there, remove it. ## What Does NOT Belong in the Repo - Personal planning/workflow artifacts (AI session plans, task lists, etc.) - Large static data that could be fetched at runtime - Generated files that aren't part of the build output -- Experimental features without prior discussion ## Commit Style - Prefer conventional commits (`feat:`, `fix:`, `chore:`, `docs:`). @@ -69,7 +61,7 @@ AI coding tools are welcome, but **you are responsible for what you submit**: ## Reporting Bugs Please include: - OS version -- app version / commit hash -- repro steps -- expected vs actual behavior -- logs/screenshots when possible +- App version / commit hash +- Repro steps +- Expected vs actual behavior +- Logs/screenshots when possible diff --git a/src/renderer/components/team/TeamDetailView.tsx b/src/renderer/components/team/TeamDetailView.tsx index b1226889..4a01b5c0 100644 --- a/src/renderer/components/team/TeamDetailView.tsx +++ b/src/renderer/components/team/TeamDetailView.tsx @@ -2088,6 +2088,22 @@ export const TeamDetailView = ({ teamName }: TeamDetailViewProps): React.JSX.Ele .getState() .openTab({ type: 'graph', label: `${data.config.name} Graph`, teamName }); }} + onSendMessage={(memberName) => { + setSendDialogRecipient(memberName); + setSendDialogDefaultText(undefined); + setSendDialogDefaultChip(undefined); + setSendDialogOpen(true); + }} + onOpenTaskDetail={(taskId) => { + const task = data.tasks.find((t) => t.id === taskId); + if (task) setSelectedTask(task); + }} + onOpenMemberProfile={(memberName) => { + setSendDialogRecipient(memberName); + setSendDialogDefaultText(undefined); + setSendDialogDefaultChip(undefined); + setSendDialogOpen(true); + }} /> )} diff --git a/src/renderer/features/agent-graph/ui/TeamGraphOverlay.tsx b/src/renderer/features/agent-graph/ui/TeamGraphOverlay.tsx index 5e7f7aca..9a7afd7d 100644 --- a/src/renderer/features/agent-graph/ui/TeamGraphOverlay.tsx +++ b/src/renderer/features/agent-graph/ui/TeamGraphOverlay.tsx @@ -15,32 +15,41 @@ export interface TeamGraphOverlayProps { teamName: string; onClose: () => void; onPinAsTab?: () => void; + onSendMessage?: (memberName: string) => void; + onOpenTaskDetail?: (taskId: string) => void; + onOpenMemberProfile?: (memberName: string) => void; } export const TeamGraphOverlay = ({ teamName, onClose, onPinAsTab, + onSendMessage, + onOpenTaskDetail, + onOpenMemberProfile, }: TeamGraphOverlayProps): React.JSX.Element => { const graphData = useTeamGraphAdapter(teamName); const events: GraphEventPort = { - onNodeClick: useCallback((_ref: GraphDomainRef) => { - // Popover shown by GraphView internally - }, []), - onNodeDoubleClick: useCallback((ref: GraphDomainRef) => { - // TODO: open TaskDetailDialog or MemberDetailDialog based on ref.kind - console.log('Double-click:', ref); - }, []), - onSendMessage: useCallback((_memberName: string, _teamName: string) => { - // TODO: open SendMessageDialog - }, []), - onOpenTaskDetail: useCallback((_taskId: string, _teamName: string) => { - // TODO: open TaskDetailDialog - }, []), - onBackgroundClick: useCallback(() => { - // Deselect handled by GraphView - }, []), + onNodeDoubleClick: useCallback( + (ref: GraphDomainRef) => { + if (ref.kind === 'task') onOpenTaskDetail?.(ref.taskId); + else if (ref.kind === 'member') onOpenMemberProfile?.(ref.memberName); + }, + [onOpenTaskDetail, onOpenMemberProfile] + ), + onSendMessage: useCallback( + (memberName: string) => onSendMessage?.(memberName), + [onSendMessage] + ), + onOpenTaskDetail: useCallback( + (taskId: string) => onOpenTaskDetail?.(taskId), + [onOpenTaskDetail] + ), + onOpenMemberProfile: useCallback( + (memberName: string) => onOpenMemberProfile?.(memberName), + [onOpenMemberProfile] + ), }; return (