Conversation
- Introduced hooks to enable automated workflows triggered by specific events during GitHub Copilot sessions. - Added documentation for hooks in AGENTS.md and README.md. - Created a new directory structure for hooks, including README.md and hooks.json files. - Implemented two example hooks: Session Auto-Commit and Session Logger. - Developed scripts for logging session events and auto-committing changes. - Enhanced validation and parsing for hook metadata. - Updated build and validation scripts to accommodate new hooks functionality.
There was a problem hiding this comment.
Pull request overview
This PR introduces Hooks as a first-class resource type across the repo, including documentation generation, website data generation, and a new website page for browsing/downloading hook bundles.
Changes:
- Adds hook folder examples under
hooks/(withREADME.md,hooks.json, and scripts). - Extends build/eng scripts to parse hook metadata and generate
docs/README.hooks.mdpluswebsite/data/hooks.json. - Adds a Hooks landing page and homepage/nav integration in the website.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| website/src/scripts/utils.ts | Adds hook type detection/labels/icons. |
| website/src/scripts/pages/index.ts | Includes hooks in homepage manifest count rendering. |
| website/src/scripts/pages/hooks.ts | New Hooks listing page logic (filters/search/download ZIP). |
| website/src/pages/index.astro | Adds Hooks card to homepage. |
| website/src/pages/hooks.astro | New Hooks page markup (search/filters/list/modal). |
| website/src/layouts/BaseLayout.astro | Adds Hooks to top navigation. |
| hooks/session-logger/log-session-start.sh | New hook script for sessionStart logging. |
| hooks/session-logger/log-session-end.sh | New hook script for sessionEnd logging. |
| hooks/session-logger/log-prompt.sh | New hook script for userPromptSubmitted logging. |
| hooks/session-logger/hooks.json | Hook configuration mapping events to scripts. |
| hooks/session-logger/README.md | Documentation for the Session Logger hook. |
| hooks/session-auto-commit/hooks.json | Hook configuration for auto-commit on sessionEnd. |
| hooks/session-auto-commit/auto-commit.sh | Script to auto-commit/push at session end. |
| hooks/session-auto-commit/README.md | Documentation for the Session Auto-Commit hook. |
| eng/yaml-parser.mjs | Adds parseHookMetadata() for hook folders. |
| eng/validate-collections.mjs | Adds hook as a valid collection item kind (with validation). |
| eng/update-readme.mjs | Generates Hooks README section and writes docs/README.hooks.md. |
| eng/generate-website-data.mjs | Generates hooks.json, includes hooks in search index + manifest counts. |
| eng/constants.mjs | Adds hooks templates/dir/constants and install URL. |
| eng/collection-to-plugin.mjs | Adds hook support when converting collections to plugins. |
| docs/README.hooks.md | New generated Hooks catalog README. |
| README.md | Adds Hooks to top-level README navigation + overview text. |
| AGENTS.md | Documents Hooks as a repo resource type and contribution checklist. |
| // Hooks | ||
| const hooks = items.filter((item) => item.kind === "hook"); | ||
| if (hooks.length > 0) { | ||
| lines.push("### Hooks"); | ||
| lines.push(""); | ||
| lines.push("| Hook | Description | Event |"); | ||
| lines.push("|------|-------------|-------|"); | ||
| for (const item of hooks) { | ||
| const name = getDisplayName(item.path, "hook"); | ||
| const description = | ||
| item.frontmatter?.description || item.frontmatter?.name || name; | ||
| const event = item.frontmatter?.event || "N/A"; | ||
| lines.push(`| \`${name}\` | ${description} | ${event} |`); | ||
| } | ||
| lines.push(""); |
There was a problem hiding this comment.
The plugin README generator’s Hooks table uses frontmatter.event, but hook events in this PR are defined in hooks.json and the hook README frontmatter doesn’t include an event field. This will render N/A even when events exist. Consider extracting event names from hooks.json (similar to parseHookMetadata) when building the plugin README.
| @@ -48,9 +50,9 @@ npm run skill:create -- --name <skill-name> | |||
|
|
|||
| ## Development Workflow | |||
|
|
|||
| ### Working with Agents, Prompts, Instructions, and Skills | |||
| ### Working with Agents, Prompts, Instructions, Skills, and Hooks | |||
|
|
|||
| All agent files (`*.agent.md`), prompt files (`*.prompt.md`), and instruction files (`*.instructions.md`) must include proper markdown front matter. Agent Skills are folders containing a `SKILL.md` file with frontmatter and optional bundled assets: | |||
| All agent files (`*.agent.md`), prompt files (`*.prompt.md`), instruction files (`*.instructions.md`), and hook files (`*.hook.md`) must include proper markdown front matter. Agent Skills are folders containing a `SKILL.md` file with frontmatter and optional bundled assets: | |||
|
|
|||
There was a problem hiding this comment.
This doc still describes hooks as .hook.md files (repository structure and frontmatter rules), but the implementation in this PR treats hooks as folders containing README.md + hooks.json. Please update the .hook.md references to match the folder-based hook format to avoid confusing contributors.
| This hook provides detailed logging of Copilot coding agent activity: | ||
| - Session start/end times | ||
| - User prompts and questions | ||
| - Session duration | ||
| - Working directory context | ||
|
|
||
| ## Features | ||
|
|
||
| - **Complete Audit Trail**: Track all Copilot interactions | ||
| - **Structured Logging**: JSON format for easy parsing | ||
| - **Searchable History**: Review past sessions and prompts | ||
| - **Analytics Ready**: Export data for usage analysis | ||
| - **Privacy Aware**: Configurable to exclude sensitive data | ||
|
|
||
| ## Installation | ||
|
|
||
| 1. Copy this hook folder to your repository's `.github/hooks/` directory: | ||
| ```bash | ||
| cp -r hooks/session-logger .github/hooks/ | ||
| ``` | ||
|
|
||
| 2. Create the logs directory: | ||
| ```bash | ||
| mkdir -p logs/copilot | ||
| ``` | ||
|
|
||
| 3. Ensure scripts are executable: | ||
| ```bash | ||
| chmod +x .github/hooks/session-logger/*.sh | ||
| ``` | ||
|
|
||
| 4. Commit the hook configuration to your repository's default branch | ||
|
|
||
| ## Log Format | ||
|
|
||
| Logs are written to `logs/copilot/session.log` in JSON format: | ||
|
|
||
| ```json | ||
| { | ||
| "timestamp": "2024-01-15T10:30:00Z", | ||
| "event": "sessionStart", | ||
| "sessionId": "abc123", | ||
| "cwd": "/workspace/project" | ||
| } | ||
| ``` |
There was a problem hiding this comment.
The README claims the hook logs user prompts, session duration, and includes fields like sessionId in the JSON example, but the provided scripts currently only log timestamps/events (and don’t record prompt content, duration, or sessionId). Either update the scripts to capture these fields from the hook input, or adjust the README/features/example JSON to reflect what is actually logged.
|
@aaronpowell I've opened a new pull request, #691, to work on those changes. Once the pull request is ready, I'll request review from you. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com>
Fix path matching in getResourceType to handle relative paths
- Fix getResourceType() to match relative paths like hooks/<name>/README.md and skills/<name>/SKILL.md using regex instead of string includes - Extract hook events from hooks.json via parseHookMetadata() instead of non-existent frontmatter.event field in plugin README generation - Update AGENTS.md to describe hooks as folder-based (README.md + hooks.json) instead of .hook.md files - Update session-logger README to accurately reflect what scripts log (remove references to sessionId, duration, prompt content)
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
hooks/session-auto-commit/auto-commit.sh:43
- Auto-pushing on every
sessionEndcan have surprising effects (e.g., pushing to a protected branch, pushing partial work, or failing due to missing auth). Consider making the push step opt-in (env var) and/or explicitly targeting a remote/branch to avoid unintended repository changes.
# Attempt to push
if git push 2>/dev/null; then
echo "✅ Changes committed and pushed successfully"
else
echo "⚠️ Push failed - changes committed locally"
fi
|
|
||
| **For Hooks:** | ||
| 1. Create a new folder in `hooks/` with a descriptive name | ||
| 2. Create `README.md` with proper frontmatter (name, description, hooks, tags) |
There was a problem hiding this comment.
Hooks are described above as extracting events from hooks.json, but this step lists hooks as a frontmatter field. That’s inconsistent with the current hook schema (README frontmatter is name, description, optional tags). Consider removing hooks from the frontmatter list here to avoid confusing contributors.
| 2. Create `README.md` with proper frontmatter (name, description, hooks, tags) | |
| 2. Create `README.md` with proper frontmatter (name, description, optional `tags`) |
| # Log session start (use jq for proper JSON encoding) | ||
| jq -Rn --arg timestamp "$TIMESTAMP" --arg cwd "$CWD" '{"timestamp":$timestamp,"event":"sessionStart","cwd":$cwd}' >> logs/copilot/session.log |
There was a problem hiding this comment.
log-session-start.sh depends on jq and will fail (due to set -euo pipefail) if jq isn't installed in the environment running the hook. Consider adding a command -v jq check with a fallback logging implementation (or a clear, non-fatal message) so the hook doesn’t break session workflows unexpectedly.
| 2. Create the logs directory: | ||
| ```bash | ||
| mkdir -p logs/copilot | ||
| ``` | ||
|
|
||
| 3. Ensure scripts are executable: | ||
| ```bash | ||
| chmod +x .github/hooks/session-logger/*.sh | ||
| ``` | ||
|
|
||
| 4. Commit the hook configuration to your repository's default branch |
There was a problem hiding this comment.
The README doesn’t mention that log-session-start.sh requires jq. Since missing jq will cause the hook to fail, document this dependency (or update the script to avoid requiring it) so installation steps are complete and predictable.
| 2. Create the logs directory: | |
| ```bash | |
| mkdir -p logs/copilot | |
| ``` | |
| 3. Ensure scripts are executable: | |
| ```bash | |
| chmod +x .github/hooks/session-logger/*.sh | |
| ``` | |
| 4. Commit the hook configuration to your repository's default branch | |
| 2. Install the `jq` command-line JSON processor (required by `log-session-start.sh`): | |
| ```bash | |
| # macOS (Homebrew) | |
| brew install jq | |
| # Debian/Ubuntu | |
| sudo apt-get update && sudo apt-get install -y jq | |
| # Fedora/RHEL | |
| sudo dnf install -y jq |
-
Create the logs directory:
mkdir -p logs/copilot
-
Ensure scripts are executable:
chmod +x .github/hooks/session-logger/*.sh -
Commit the hook configuration to your repository's default branch
| # Stage all changes | ||
| git add -A | ||
|
|
||
| # Create timestamped commit | ||
| TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') | ||
| git commit -m "auto-commit: $TIMESTAMP" --no-verify 2>/dev/null || { | ||
| echo "⚠️ Commit failed" | ||
| exit 0 | ||
| } |
There was a problem hiding this comment.
This stages all changes (git add -A) and commits with --no-verify, which can easily commit generated artifacts or sensitive files and bypass local safeguards. Consider making the staged paths configurable (allowlist), and/or avoiding --no-verify by default (opt-in via env var) to reduce accidental commits.
This issue also appears on line 38 of the same file.
| # Stage all changes | |
| git add -A | |
| # Create timestamped commit | |
| TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') | |
| git commit -m "auto-commit: $TIMESTAMP" --no-verify 2>/dev/null || { | |
| echo "⚠️ Commit failed" | |
| exit 0 | |
| } | |
| # Stage changes (allowlist via AUTO_COMMIT_PATHS, default to current directory) | |
| AUTO_COMMIT_PATHS=${AUTO_COMMIT_PATHS:-.} | |
| git add -- ${AUTO_COMMIT_PATHS} | |
| # Create timestamped commit | |
| TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') | |
| COMMIT_ARGS=(-m "auto-commit: $TIMESTAMP") | |
| if [[ "${AUTO_COMMIT_NO_VERIFY:-}" == "true" ]]; then | |
| COMMIT_ARGS+=("--no-verify") | |
| fi | |
| if ! git commit "${COMMIT_ARGS[@]}" 2>/dev/null; then | |
| echo "⚠️ Commit failed" | |
| exit 0 | |
| fi |
This pull request adds support for "Hooks" as a new resource type in the Awesome GitHub Copilot repository, enabling automated workflows triggered by specific development events. The changes span documentation, code generation scripts, and website data processing, ensuring hooks are first-class citizens alongside agents, prompts, instructions, and skills.