diff --git a/.claude/metadata-updater.sh b/.claude/metadata-updater.sh new file mode 100755 index 000000000..c64ba9cf6 --- /dev/null +++ b/.claude/metadata-updater.sh @@ -0,0 +1,136 @@ +#!/usr/bin/env bash +# Metadata Updater Hook for Agent Orchestrator +# +# This PostToolUse hook automatically updates session metadata when: +# - gh pr create: extracts PR URL and writes to metadata +# - git checkout -b / git switch -c: extracts branch name and writes to metadata +# - gh pr merge: updates status to "merged" + +set -euo pipefail + +# Configuration +AO_DATA_DIR="${AO_DATA_DIR:-$HOME/.ao-sessions}" + +# Read hook input from stdin +input=$(cat) + +# Extract fields from JSON (using jq if available, otherwise basic parsing) +if command -v jq &>/dev/null; then + tool_name=$(echo "$input" | jq -r '.tool_name // empty') + command=$(echo "$input" | jq -r '.tool_input.command // empty') + output=$(echo "$input" | jq -r '.tool_response // empty') + exit_code=$(echo "$input" | jq -r '.exit_code // 0') +else + # Fallback: basic JSON parsing without jq + tool_name=$(echo "$input" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4 || echo "") + command=$(echo "$input" | grep -o '"command"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4 || echo "") + output=$(echo "$input" | grep -o '"tool_response"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4 || echo "") + exit_code=$(echo "$input" | grep -o '"exit_code"[[:space:]]*:[[:space:]]*[0-9]*' | grep -o '[0-9]*$' || echo "0") +fi + +# Only process successful commands (exit code 0) +if [[ "$exit_code" -ne 0 ]]; then + echo '{}' + exit 0 +fi + +# Only process Bash tool calls +if [[ "$tool_name" != "Bash" ]]; then + echo '{}' # Empty JSON output + exit 0 +fi + +# Validate AO_SESSION is set +if [[ -z "${AO_SESSION:-}" ]]; then + echo '{"systemMessage": "AO_SESSION environment variable not set, skipping metadata update"}' + exit 0 +fi + +# Construct metadata file path +# AO_DATA_DIR is already set to the project-specific sessions directory +metadata_file="$AO_DATA_DIR/$AO_SESSION" + +# Ensure metadata file exists +if [[ ! -f "$metadata_file" ]]; then + echo '{"systemMessage": "Metadata file not found: '"$metadata_file"'"}' + exit 0 +fi + +# Update a single key in metadata +update_metadata_key() { + local key="$1" + local value="$2" + + # Create temp file + local temp_file="${metadata_file}.tmp" + + # Escape special sed characters in value (& | / \) + local escaped_value=$(echo "$value" | sed 's/[&|\/]/\\&/g') + + # Check if key already exists + if grep -q "^$key=" "$metadata_file" 2>/dev/null; then + # Update existing key + sed "s|^$key=.*|$key=$escaped_value|" "$metadata_file" > "$temp_file" + else + # Append new key + cp "$metadata_file" "$temp_file" + echo "$key=$value" >> "$temp_file" + fi + + # Atomic replace + mv "$temp_file" "$metadata_file" +} + +# ============================================================================ +# Command Detection and Parsing +# ============================================================================ + +# Detect: gh pr create +if [[ "$command" =~ ^gh[[:space:]]+pr[[:space:]]+create ]]; then + # Extract PR URL from output + pr_url=$(echo "$output" | grep -Eo 'https://github[.]com/[^/]+/[^/]+/pull/[0-9]+' | head -1) + + if [[ -n "$pr_url" ]]; then + update_metadata_key "pr" "$pr_url" + update_metadata_key "status" "pr_open" + echo '{"systemMessage": "Updated metadata: PR created at '"$pr_url"'"}' + exit 0 + fi +fi + +# Detect: git checkout -b or git switch -c +if [[ "$command" =~ ^git[[:space:]]+checkout[[:space:]]+-b[[:space:]]+([^[:space:]]+) ]] || \ + [[ "$command" =~ ^git[[:space:]]+switch[[:space:]]+-c[[:space:]]+([^[:space:]]+) ]]; then + branch="${BASH_REMATCH[1]}" + + if [[ -n "$branch" ]]; then + update_metadata_key "branch" "$branch" + echo '{"systemMessage": "Updated metadata: branch = '"$branch"'"}' + exit 0 + fi +fi + +# Detect: git checkout (without -b) or git switch (without -c) +# Only update if the branch name looks like a feature branch (contains / or -) +if [[ "$command" =~ ^git[[:space:]]+checkout[[:space:]]+([^[:space:]-]+[/-][^[:space:]]+) ]] || \ + [[ "$command" =~ ^git[[:space:]]+switch[[:space:]]+([^[:space:]-]+[/-][^[:space:]]+) ]]; then + branch="${BASH_REMATCH[1]}" + + # Avoid updating for checkout of commits/tags + if [[ -n "$branch" && "$branch" != "HEAD" ]]; then + update_metadata_key "branch" "$branch" + echo '{"systemMessage": "Updated metadata: branch = '"$branch"'"}' + exit 0 + fi +fi + +# Detect: gh pr merge +if [[ "$command" =~ ^gh[[:space:]]+pr[[:space:]]+merge ]]; then + update_metadata_key "status" "merged" + echo '{"systemMessage": "Updated metadata: status = merged"}' + exit 0 +fi + +# No matching command, exit silently +echo '{}' +exit 0 diff --git a/README.md b/README.md index 4686e11d5..f94b69fa0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # CUDA Samples + + Samples for CUDA Developers which demonstrates features in CUDA Toolkit. This version supports [CUDA Toolkit 13.1](https://developer.nvidia.com/cuda-downloads). ## Release Notes diff --git a/agent-orchestrator.yaml b/agent-orchestrator.yaml new file mode 100644 index 000000000..8d6bfa232 --- /dev/null +++ b/agent-orchestrator.yaml @@ -0,0 +1,19 @@ +dataDir: ~/.agent-orchestrator +worktreeDir: ~/.worktrees +port: 3000 +defaults: + runtime: tmux + agent: claude-code + workspace: worktree + notifiers: + - desktop +projects: + cuda-samples: + repo: Jcf123456789/cuda-samples + path: /home/ybh/cuda-samples + defaultBranch: master + agentRules: |- + Always run tests before pushing. + Use conventional commits (feat:, fix:, chore:, docs:, refactor:, test:). + Link issue numbers in commit messages. + Write clear commit messages that explain WHY, not just WHAT.