Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/skills/sync-ai-instructions/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
name: sync-ai-instructions
description: Copy repository AI instruction files from `.github/instructions/*` into `.agents/rules/` by running the bundled sync script. Use when Codex needs to sync GitHub Copilot instruction files into agent rule files, refresh `.agents/rules`, or keep local AI rule directories aligned with `.github/instructions`; do not hand-create destination files.
---

# Sync AI Instructions

## Overview

Copy each regular file from `.github/instructions/` into `.agents/rules/`
while preserving file names and leaving unrelated target files alone.

## Workflow

1. Run the bundled script from the repository root:

```bash
bash .github/skills/sync-ai-instructions/scripts/sync_ai_instructions.sh
```

2. If running from another directory, pass the repository root:

```bash
bash /path/to/repo/.github/skills/sync-ai-instructions/scripts/sync_ai_instructions.sh /path/to/repo
```

3. Verify the output lists copied files and a final synced count.
4. Report the target path and any files copied.

## Safety Rules

- Run the bundled script instead of recreating each copied file manually.
- Copy only files directly under `.github/instructions/`.
- Create `.agents/rules/` when it does not exist.
- Overwrite matching files in `.agents/rules/`.
- Do not delete existing files in `.agents/rules/`.
- Do not copy `.github/copilot-instructions.md`.
4 changes: 4 additions & 0 deletions .github/skills/sync-ai-instructions/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Sync AI Instructions"
short_description: "Copy GitHub instructions into .agents rules"
default_prompt: "Use $sync-ai-instructions to run the bundled script that copies .github/instructions files into .agents/rules and verify the synced rule files."
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env bash
set -euo pipefail

usage() {
cat <<'USAGE'
Usage: sync_ai_instructions.sh [repo-root]

Copy files from .github/instructions/ into .agents/rules/.
USAGE
}

if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
exit 0
fi

if [[ "$#" -gt 1 ]]; then
usage >&2
exit 2
fi

repo_root="${1:-.}"
repo_root="$(cd "$repo_root" && pwd -P)"
source_dir="$repo_root/.github/instructions"
target_dir="$repo_root/.agents/rules"

if [[ ! -d "$source_dir" ]]; then
printf 'Source instructions directory not found: %s\n' "$source_dir" >&2
exit 1
fi

instruction_files=()
while IFS= read -r source_file; do
instruction_files+=("$source_file")
done < <(find "$source_dir" -maxdepth 1 -type f | LC_ALL=C sort)

if [[ "${#instruction_files[@]}" -eq 0 ]]; then
printf 'No instruction files found in: %s\n' "$source_dir" >&2
exit 1
fi

mkdir -p "$target_dir"

copied=0
for source_file in "${instruction_files[@]}"; do
file_name="$(basename "$source_file")"
cp -p "$source_file" "$target_dir/$file_name"
printf 'Copied %s\n' ".agents/rules/$file_name"
copied=$((copied + 1))
done

printf 'Synced %d instruction file(s) to %s\n' "$copied" "$target_dir"
43 changes: 43 additions & 0 deletions .github/skills/sync-ai-skills/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
name: sync-ai-skills
description: Copy local repository skills from `.github/skills` into AI skill target directories by running the bundled sync script. Use when asked to install, refresh, or sync repository skills for Codex or Google Antigravity discovery, including `${CODEX_HOME:-$HOME/.codex}/skills` and `.agent/skills`; do not hand-create copied skill files.
---

# Sync AI Skills

Copy each skill folder from `.github/skills` to Codex's runtime skills
directory and this repository's local `.agent/skills` directory for Google
Antigravity.

## Workflow

1. Run the bundled script from the repository root:

```bash
bash .github/skills/sync-ai-skills/scripts/sync_ai_skills.sh
```

2. If running from another directory, pass the repository root:

```bash
bash /path/to/repo/.github/skills/sync-ai-skills/scripts/sync_ai_skills.sh /path/to/repo
```

3. Verify the output lists copied skills and `Verified ... hash(es) match`
lines for each target.
4. Report copied skills and any skipped target.

## Safety Rules

- Run the bundled script instead of recreating each copied skill file manually.
- Do not create `${CODEX_HOME:-$HOME/.codex}` if it does not exist.
- Create `.agent/skills` when it does not exist.
- Copy only direct skill folders under `.github/skills`.
- Do not delete existing target skills.
- If a target skill already exists, overwrite files by copy operation and
report it.
- Fail the sync if any copied source file is missing or has a different
SHA-256 hash in the destination.
- Do not treat extra files already present in a target skill directory as
failure; this sync does not delete target files.
- Request approval before running a command that copies outside the sandbox.
4 changes: 4 additions & 0 deletions .github/skills/sync-ai-skills/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Sync AI Skills"
short_description: "Copy .github skills to AI skill directories"
default_prompt: "Use $sync-ai-skills to run the bundled script that copies .github/skills into ${CODEX_HOME:-$HOME/.codex}/skills and .agent/skills, then verify matching hashes in the script output."
139 changes: 139 additions & 0 deletions .github/skills/sync-ai-skills/scripts/sync_ai_skills.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/usr/bin/env bash
set -euo pipefail

usage() {
cat <<'USAGE'
Usage: sync_ai_skills.sh [repo-root]

Copy skill folders from .github/skills/ into:
- ${CODEX_HOME:-$HOME/.codex}/skills when Codex home exists
- .agent/skills inside the repository for Google Antigravity
USAGE
}

if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
exit 0
fi

if [[ "$#" -gt 1 ]]; then
usage >&2
exit 2
fi

repo_root="${1:-.}"
repo_root="$(cd "$repo_root" && pwd -P)"
source_dir="$repo_root/.github/skills"
codex_root="${CODEX_HOME:-$HOME/.codex}"
antigravity_target="$repo_root/.agent/skills"

if [[ ! -d "$source_dir" ]]; then
printf 'Source skills directory not found: %s\n' "$source_dir" >&2
exit 1
fi

skill_dirs=()
while IFS= read -r skill_dir; do
skill_dirs+=("$skill_dir")
done < <(find "$source_dir" -mindepth 1 -maxdepth 1 -type d | LC_ALL=C sort)

if [[ "${#skill_dirs[@]}" -eq 0 ]]; then
printf 'No skill directories found in: %s\n' "$source_dir" >&2
exit 1
fi

hash_file() {
local file_path="$1"
local hash_output

if command -v sha256sum >/dev/null 2>&1; then
hash_output="$(sha256sum "$file_path")"
printf '%s\n' "${hash_output%% *}"
return
fi

if command -v shasum >/dev/null 2>&1; then
hash_output="$(shasum -a 256 "$file_path")"
printf '%s\n' "${hash_output%% *}"
return
fi

printf 'Neither sha256sum nor shasum is available for verification.\n' >&2
exit 1
}

verify_skill_copy() {
local source_skill_dir="$1"
local target_skill_dir="$2"
local target_label="$3"
local skill_name
local verified_files=0

skill_name="$(basename "$source_skill_dir")"

if [[ ! -d "$target_skill_dir" ]]; then
printf 'Verification failed: missing destination skill directory: %s\n' \
"$target_skill_dir" >&2
exit 1
fi

while IFS= read -r source_file; do
local relative_path
local target_file
local source_hash
local target_hash

relative_path="${source_file#"$source_skill_dir"/}"
target_file="$target_skill_dir/$relative_path"

if [[ ! -f "$target_file" ]]; then
printf 'Verification failed: missing copied file: %s\n' \
"$target_file" >&2
exit 1
fi

source_hash="$(hash_file "$source_file")"
target_hash="$(hash_file "$target_file")"

if [[ "$source_hash" != "$target_hash" ]]; then
printf 'Verification failed: hash mismatch for %s in %s\n' \
"$relative_path" "$target_label" >&2
printf 'Source: %s\nDestination: %s\n' \
"$source_hash" "$target_hash" >&2
exit 1
fi

verified_files=$((verified_files + 1))
done < <(find "$source_skill_dir" -type f | LC_ALL=C sort)

printf 'Verified %s/%s: %d source file hash(es) match destination\n' \
"$target_label" "$skill_name" "$verified_files"
}

copy_skills_to_target() {
local target_dir="$1"
local target_label="$2"

mkdir -p "$target_dir"
printf 'Syncing %d skill(s) to %s: %s\n' \
"${#skill_dirs[@]}" "$target_label" "$target_dir"

local skill_dir
local skill_name
for skill_dir in "${skill_dirs[@]}"; do
skill_name="$(basename "$skill_dir")"
cp -R "$skill_dir" "$target_dir/"
printf 'Copied %s -> %s/%s\n' "$skill_name" "$target_label" "$skill_name"
verify_skill_copy "$skill_dir" "$target_dir/$skill_name" "$target_label"
done
}

if [[ -d "$codex_root" ]]; then
copy_skills_to_target "$codex_root/skills" "Codex skills"
else
printf 'Skipping Codex skills: Codex home does not exist: %s\n' "$codex_root"
fi

copy_skills_to_target "$antigravity_target" "Google Antigravity skills"

printf 'Synced %d skill(s) from %s\n' "${#skill_dirs[@]}" "$source_dir"
44 changes: 0 additions & 44 deletions .github/skills/sync-codex-skills/SKILL.md

This file was deleted.

4 changes: 0 additions & 4 deletions .github/skills/sync-codex-skills/agents/openai.yaml

This file was deleted.

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,7 @@ tests/quality/spec_audits

# Cookie jars produced by scripts/dev-login.mjs
.auth/

.agents
.agent
devcontainer-lock.json
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.13/schema.json",
"$schema": "https://biomejs.dev/schemas/2.4.14/schema.json",
"assist": {
"actions": {
"source": {
Expand Down
Loading
Loading