blob: 23097448e536b23d2e78844000760beccb9e4873 [file]
#!/usr/bin/env bash
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Set up AI coding agent integration with TinkerPop's Agent Skills.
#
# TinkerPop maintains development guidance as an Agent Skill in .skills/tinkerpop-dev/.
# Different AI coding tools discover skills in different directories. This script
# creates the necessary symlinks or shims so your tool can find the skill.
#
# Usage:
# bin/agent-setup.sh <agent>
# bin/agent-setup.sh --list
# bin/agent-setup.sh --all
#
# Examples:
# bin/agent-setup.sh claude # Set up for Claude Code
# bin/agent-setup.sh kiro # Set up for Kiro
# bin/agent-setup.sh --all # Set up for all supported agents
#
# Supported agents:
# claude - Claude Code (.claude/skills/)
# copilot - GitHub Copilot (.github/skills/ and .agents/skills/)
# cursor - Cursor (.cursor/skills/)
# codex - OpenAI Codex (.codex/skills/)
# junie - JetBrains Junie (.junie/skills/)
# kiro - Kiro (.kiro/skills/)
set -uo pipefail
SKILL_DIR=".skills/tinkerpop-dev"
SKILL_NAME="tinkerpop-dev"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m'
ok() { echo -e " ${GREEN}✓${NC} $1"; }
skip() { echo -e " ${YELLOW}○${NC} $1"; }
bad() { echo -e " ${RED}✗${NC} $1"; }
usage() {
echo "Usage: bin/agent-setup.sh <agent|--list|--all>"
echo ""
echo "Agents: claude, copilot, cursor, codex, junie, kiro"
echo ""
echo "Options:"
echo " --list List supported agents and their skill discovery paths"
echo " --all Set up shims for all supported agents"
echo " --help Show this message"
}
# Verify we're in the repo root
if [[ ! -d "$SKILL_DIR" ]]; then
bad "Cannot find $SKILL_DIR — run this script from the TinkerPop repository root."
exit 1
fi
# Create a symlink from a tool's skill directory to our canonical skill
setup_symlink() {
local tool_name="$1"
local target_dir="$2"
mkdir -p "$target_dir"
local link_path="$target_dir/$SKILL_NAME"
if [[ -L "$link_path" ]]; then
skip "$tool_name: symlink already exists at $link_path"
return 0
fi
if [[ -e "$link_path" ]]; then
bad "$tool_name: $link_path already exists and is not a symlink — skipping"
return 1
fi
# Compute relative path from target_dir to SKILL_DIR
local rel_path
rel_path=$(python3 -c "import os.path; print(os.path.relpath('$SKILL_DIR', '$target_dir'))" 2>/dev/null)
if [[ -z "$rel_path" ]]; then
# Fallback if python3 not available
rel_path=$(perl -e 'use File::Spec; print File::Spec->abs2rel("'"$SKILL_DIR"'", "'"$target_dir"'")' 2>/dev/null)
fi
if [[ -z "$rel_path" ]]; then
bad "$tool_name: could not compute relative path (need python3 or perl)"
return 1
fi
ln -s "$rel_path" "$link_path"
ok "$tool_name: created symlink $link_path -> $rel_path"
}
# Kiro doesn't follow symlinks in .kiro/skills/, so we copy the skill directory
# instead. See: https://github.com/kirodotdev/Kiro/issues (symlink support).
setup_kiro() {
local target_dir=".kiro/skills/$SKILL_NAME"
if [[ -d "$target_dir" ]]; then
rm -rf "$target_dir"
skip "kiro: removed existing copy at $target_dir"
fi
mkdir -p ".kiro/skills"
cp -r "$SKILL_DIR" "$target_dir"
ok "kiro: copied skill to $target_dir"
echo ""
echo -e " ${YELLOW}NOTE:${NC} Kiro uses a copy, not a symlink. If you update the skill in"
echo -e " $SKILL_DIR, re-run this script to sync the changes."
}
setup_agent() {
local agent="$1"
case "$agent" in
claude)
setup_symlink "claude" ".claude/skills"
;;
copilot)
setup_symlink "copilot (.github)" ".github/skills"
setup_symlink "copilot (.agents)" ".agents/skills"
;;
cursor)
setup_symlink "cursor" ".cursor/skills"
;;
codex)
setup_symlink "codex" ".codex/skills"
;;
junie)
setup_symlink "junie" ".junie/skills"
;;
kiro)
setup_kiro
;;
*)
bad "Unknown agent: $agent"
echo ""
usage
return 1
;;
esac
}
list_agents() {
echo "Supported agents and their skill discovery paths:"
echo ""
echo " claude .claude/skills/$SKILL_NAME/ -> symlink to $SKILL_DIR"
echo " copilot .github/skills/$SKILL_NAME/ -> symlink to $SKILL_DIR"
echo " .agents/skills/$SKILL_NAME/ -> symlink to $SKILL_DIR"
echo " cursor .cursor/skills/$SKILL_NAME/ -> symlink to $SKILL_DIR"
echo " codex .codex/skills/$SKILL_NAME/ -> symlink to $SKILL_DIR"
echo " junie .junie/skills/$SKILL_NAME/ -> symlink to $SKILL_DIR"
echo " kiro .kiro/skills/$SKILL_NAME/ -> copy of $SKILL_DIR (re-run to sync)"
}
# --- Main ---
if [[ $# -eq 0 ]]; then
usage
exit 1
fi
case "$1" in
--help|-h)
usage
;;
--list)
list_agents
;;
--all)
echo "Setting up all agent integrations..."
echo ""
for agent in claude copilot cursor codex junie kiro; do
setup_agent "$agent"
done
echo ""
echo "Done. Symlinked directories and generated files are gitignored."
echo "Add them to .gitignore if they aren't already."
;;
*)
echo "Setting up $1..."
echo ""
setup_agent "$1"
;;
esac