Compare commits
3 Commits
3586f39e8e
...
4978f7effd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4978f7effd | ||
|
|
30cd8605b8 | ||
|
|
917d834d7d |
@ -1,5 +1,4 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
name: Senior Cloud Architect
|
name: Senior Cloud Architect
|
||||||
description: Expert in modern architecture design patterns, NFR requirements, and creating comprehensive architectural diagrams and documentation
|
description: Expert in modern architecture design patterns, NFR requirements, and creating comprehensive architectural diagrams and documentation
|
||||||
---
|
---
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
description: 'Debug your application to find and fix a bug'
|
name: Debug Mode Instructions
|
||||||
|
description: Debug your application to find and fix a bug
|
||||||
tools: ['edit/editFiles', 'search', 'execute/getTerminalOutput', 'execute/runInTerminal', 'read/terminalLastCommand', 'read/terminalSelection', 'search/usages', 'read/problems', 'execute/testFailure', 'web/fetch', 'web/githubRepo', 'execute/runTests']
|
tools: ['edit/editFiles', 'search', 'execute/getTerminalOutput', 'execute/runInTerminal', 'read/terminalLastCommand', 'read/terminalSelection', 'search/usages', 'read/problems', 'execute/testFailure', 'web/fetch', 'web/githubRepo', 'execute/runTests']
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
description: 'Provide principal-level software engineering guidance with focus on engineering excellence, technical leadership, and pragmatic implementation.'
|
name: Principal Software Engineer Mode Instructions
|
||||||
|
description: Provide principal-level software engineering guidance with focus on engineering excellence, technical leadership, and pragmatic implementation.
|
||||||
tools: ['changes', 'search/codebase', 'edit/editFiles', 'extensions', 'web/fetch', 'findTestFiles', 'githubRepo', 'new', 'openSimpleBrowser', 'problems', 'runCommands', 'runTasks', 'runTests', 'search', 'search/searchResults', 'runCommands/terminalLastCommand', 'runCommands/terminalSelection', 'testFailure', 'usages', 'vscodeAPI', 'github']
|
tools: ['changes', 'search/codebase', 'edit/editFiles', 'extensions', 'web/fetch', 'findTestFiles', 'githubRepo', 'new', 'openSimpleBrowser', 'problems', 'runCommands', 'runTasks', 'runTests', 'search', 'search/searchResults', 'runCommands/terminalLastCommand', 'runCommands/terminalSelection', 'testFailure', 'usages', 'vscodeAPI', 'github']
|
||||||
---
|
---
|
||||||
# Principal software engineer mode instructions
|
# Principal software engineer mode instructions
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
description: 'Expert prompt engineering and validation system for creating high-quality prompts - Brought to you by microsoft/edge-ai'
|
name: Prompt Builder Instructions
|
||||||
|
description: Expert prompt engineering and validation system for creating high-quality prompts - Brought to you by microsoft/edge-ai
|
||||||
tools: ['codebase', 'edit/editFiles', 'web/fetch', 'githubRepo', 'problems', 'runCommands', 'search', 'searchResults', 'terminalLastCommand', 'terminalSelection', 'usages', 'terraform', 'Microsoft Docs', 'context7']
|
tools: ['codebase', 'edit/editFiles', 'web/fetch', 'githubRepo', 'problems', 'runCommands', 'search', 'searchResults', 'terminalLastCommand', 'terminalSelection', 'usages', 'terraform', 'Microsoft Docs', 'context7']
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
description: "A specialized chat mode for analyzing and improving prompts. Every user input is treated as a prompt to be improved. It first provides a detailed analysis of the original prompt within a <reasoning> tag, evaluating it against a systematic framework based on OpenAI's prompt engineering best practices. Following the analysis, it generates a new, improved prompt."
|
name: Prompt Engineer
|
||||||
|
description: A specialized chat mode for analyzing and improving prompts. Every user input is treated as a prompt to be improved. It first provides a detailed analysis of the original prompt within a <reasoning> tag, evaluating it against a systematic framework based on OpenAI prompt engineering best practices. Following the analysis, it generates a new, improved prompt.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Prompt Engineer
|
# Prompt Engineer
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
description: 'Expert-level software engineering agent. Deliver production-ready, maintainable code. Execute systematically and specification-driven. Document comprehensively. Operate autonomously and adaptively.'
|
name: Software Engineer Agent v1
|
||||||
|
description: Expert-level software engineering agent. Deliver production-ready, maintainable code. Execute systematically and specification-driven. Document comprehensively. Operate autonomously and adaptively.
|
||||||
tools: ['changes', 'search/codebase', 'edit/editFiles', 'extensions', 'web/fetch', 'findTestFiles', 'githubRepo', 'new', 'openSimpleBrowser', 'problems', 'runCommands', 'runTasks', 'runTests', 'search', 'search/searchResults', 'runCommands/terminalLastCommand', 'runCommands/terminalSelection', 'testFailure', 'usages', 'vscodeAPI', 'github']
|
tools: ['changes', 'search/codebase', 'edit/editFiles', 'extensions', 'web/fetch', 'findTestFiles', 'githubRepo', 'new', 'openSimpleBrowser', 'problems', 'runCommands', 'runTasks', 'runTests', 'search', 'search/searchResults', 'runCommands/terminalLastCommand', 'runCommands/terminalSelection', 'testFailure', 'usages', 'vscodeAPI', 'github']
|
||||||
---
|
---
|
||||||
# Software Engineer Agent v1
|
# Software Engineer Agent v1
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
description: "Task planner for creating actionable implementation plans - Brought to you by microsoft/edge-ai"
|
name: Task Planner Instructions
|
||||||
name: "Task Planner Instructions"
|
description: Task planner for creating actionable implementation plans - Brought to you by microsoft/edge-ai
|
||||||
tools: ["changes", "search/codebase", "edit/editFiles", "extensions", "fetch", "findTestFiles", "githubRepo", "new", "openSimpleBrowser", "problems", "runCommands", "runNotebooks", "runTests", "search", "search/searchResults", "runCommands/terminalLastCommand", "runCommands/terminalSelection", "testFailure", "usages", "vscodeAPI", "terraform", "Microsoft Docs", "azure_get_schema_for_Bicep", "context7"]
|
tools: ['changes', 'search/codebase', 'edit/editFiles', 'extensions', 'fetch', 'findTestFiles', 'githubRepo', 'new', 'openSimpleBrowser', 'problems', 'runCommands', 'runNotebooks', 'runTests', 'search', 'search/searchResults', 'runCommands/terminalLastCommand', 'runCommands/terminalSelection', 'testFailure', 'usages', 'vscodeAPI', 'terraform', 'Microsoft Docs', 'azure_get_schema_for_Bicep', 'context7']
|
||||||
---
|
---
|
||||||
|
|
||||||
# Task Planner Instructions
|
# Task Planner Instructions
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
description: "Task research specialist for comprehensive project analysis - Brought to you by microsoft/edge-ai"
|
name: Task Researcher Instructions
|
||||||
name: "Task Researcher Instructions"
|
description: Task research specialist for comprehensive project analysis - Brought to you by microsoft/edge-ai
|
||||||
tools: ["changes", "codebase", "edit/editFiles", "extensions", "fetch", "findTestFiles", "githubRepo", "new", "openSimpleBrowser", "problems", "runCommands", "runNotebooks", "runTests", "search", "searchResults", "terminalLastCommand", "terminalSelection", "testFailure", "usages", "vscodeAPI", "terraform", "Microsoft Docs", "azure_get_schema_for_Bicep", "context7"]
|
tools: ['changes', 'codebase', 'edit/editFiles', 'extensions', 'fetch', 'findTestFiles', 'githubRepo', 'new', 'openSimpleBrowser', 'problems', 'runCommands', 'runNotebooks', 'runTests', 'search', 'searchResults', 'terminalLastCommand', 'terminalSelection', 'testFailure', 'usages', 'vscodeAPI', 'terraform', 'Microsoft Docs', 'azure_get_schema_for_Bicep', 'context7']
|
||||||
---
|
---
|
||||||
|
|
||||||
# Task Researcher Instructions
|
# Task Researcher Instructions
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
description: 'Generate technical debt remediation plans for code, tests, and documentation.'
|
name: Technical Debt Remediation Plan
|
||||||
|
description: Generate technical debt remediation plans for code, tests, and documentation.
|
||||||
tools: ['changes', 'codebase', 'edit/editFiles', 'extensions', 'web/fetch', 'findTestFiles', 'githubRepo', 'new', 'openSimpleBrowser', 'problems', 'runCommands', 'runTasks', 'runTests', 'search', 'searchResults', 'terminalLastCommand', 'terminalSelection', 'testFailure', 'usages', 'vscodeAPI', 'github']
|
tools: ['changes', 'codebase', 'edit/editFiles', 'extensions', 'web/fetch', 'findTestFiles', 'githubRepo', 'new', 'openSimpleBrowser', 'problems', 'runCommands', 'runTasks', 'runTests', 'search', 'searchResults', 'terminalLastCommand', 'terminalSelection', 'testFailure', 'usages', 'vscodeAPI', 'github']
|
||||||
---
|
---
|
||||||
# Technical Debt Remediation Plan
|
# Technical Debt Remediation Plan
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
description: 'A transcendent coding agent with quantum cognitive architecture, adversarial intelligence, and unrestricted creative freedom.'
|
name: Thinking Beast Mode
|
||||||
name: 'Thinking Beast Mode'
|
description: A transcendent coding agent with quantum cognitive architecture, adversarial intelligence, and unrestricted creative freedom.
|
||||||
---
|
---
|
||||||
|
|
||||||
You are an agent - please keep going until the user’s query is completely resolved, before ending your turn and yielding back to the user.
|
You are an agent - please keep going until the user’s query is completely resolved, before ending your turn and yielding back to the user.
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: Toyota iOS Developer
|
name: Toyota iOS Developer
|
||||||
description: 'Toyota OneApp iOS development agent. Enforces Clean Architecture, Swift Package Manager modules, async/await patterns, GraphQL networking, and project-wide standards for planning, code review, and implementation.'
|
description: Toyota OneApp iOS development agent. Enforces Clean Architecture, Swift Package Manager modules, async/await patterns, GraphQL networking, and project-wide standards for planning, code review, and implementation.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Toyota iOS Developer Agent
|
# Toyota iOS Developer Agent
|
||||||
|
|||||||
567
assets/setup.sh
567
assets/setup.sh
@ -1,358 +1,245 @@
|
|||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
# AI Assets Installer — Agents & Skills for Cursor, Windsurf, Cline, etc.
|
||||||
|
# Run from your repo root (where /assets/ lives)
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────────
|
echo "=== AI Assets Installer (Agents & Skills) ==="
|
||||||
# Mobile AI Assets Installer v2.0.0
|
echo "Popular tools supported in 2026: Cursor, Windsurf, Cline, RooCode, etc."
|
||||||
#
|
echo
|
||||||
# One script to install skills, agents, and instructions.
|
|
||||||
# Agents and instructions are discovered automatically from directories.
|
|
||||||
# Skills are read from simple text files (one install entry per line).
|
|
||||||
#
|
|
||||||
# Local: ./assets/setup.sh all ios
|
|
||||||
# Remote: export ASSETS_BASE_URL="https://gitlab.com/<org>/repo/-/raw/develop/assets"
|
|
||||||
# bash <(curl -fsSL "$ASSETS_BASE_URL/setup.sh") all ios
|
|
||||||
# ─────────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
VERSION="2.1.0"
|
ASSETS_DIR="${ASSETS_DIR:-./assets}"
|
||||||
|
AGENTS_DIR="$ASSETS_DIR/agents"
|
||||||
|
SKILLS_DIR="$ASSETS_DIR/skills"
|
||||||
|
GLOBAL_ASSETS_DIR="${GLOBAL_ASSETS_DIR:-$HOME/.agents}"
|
||||||
|
|
||||||
# ── Configuration (override with env vars) ───────────────────────────
|
# ================== PRODUCTS (easy to edit) ==================
|
||||||
# Default paths use ~/.agents/ — the tool-agnostic directory.
|
# Format: "Display Name:folder_name"
|
||||||
# The npx skills CLI copies into tool-specific dirs (~/.copilot/,
|
PRODUCTS=(
|
||||||
# ~/.claude/, ~/.cursor/) automatically.
|
"Cursor:.cursor"
|
||||||
ASSETS_BASE_URL="${ASSETS_BASE_URL:-}"
|
"Windsurf:.windsurf"
|
||||||
AGENTS_DIR="${AGENTS_DIR:-$HOME/.agents/agents}"
|
"Cline:.cline"
|
||||||
SKILLS_DIR="${SKILLS_DIR:-$HOME/.agents/skills}"
|
"RooCode:.roo"
|
||||||
INSTRUCTIONS_DIR="${INSTRUCTIONS_DIR:-./instructions}"
|
"Continue:.continue"
|
||||||
REPO_TOKEN="${REPO_TOKEN:-}"
|
"VS Code / Copilot:.vscode"
|
||||||
|
"GitHub / Copilot:.github"
|
||||||
|
"Claude Code:.claude"
|
||||||
|
# Add more here, e.g. "Aider:.aider"
|
||||||
|
)
|
||||||
|
|
||||||
# ── Colors ───────────────────────────────────────────────────────────
|
# ================== SELECT HELPERS ==================
|
||||||
RED='\033[0;31m'
|
select_items() {
|
||||||
GREEN='\033[0;32m'
|
local dir=$1
|
||||||
YELLOW='\033[1;33m'
|
local type=$2
|
||||||
BLUE='\033[0;34m'
|
local items=()
|
||||||
BOLD='\033[1m'
|
|
||||||
NC='\033[0m'
|
|
||||||
|
|
||||||
# ── Helpers ──────────────────────────────────────────────────────────
|
if [ ! -d "$dir" ]; then
|
||||||
info() { printf "${BLUE}▸${NC} %s\n" "$*"; }
|
echo "⚠️ $dir not found — skipping $type." >&2
|
||||||
ok() { printf "${GREEN}✓${NC} %s\n" "$*"; }
|
return
|
||||||
warn() { printf "${YELLOW}!${NC} %s\n" "$*"; }
|
fi
|
||||||
fail() { printf "${RED}✗${NC} %s\n" "$*" >&2; exit 1; }
|
|
||||||
heading() { printf "\n${BOLD}── %s ──${NC}\n" "$*"; }
|
|
||||||
|
|
||||||
# ── Mode Detection ───────────────────────────────────────────────────
|
if [ "$type" = "agents" ]; then
|
||||||
MODE=""
|
while IFS= read -r item; do
|
||||||
ASSETS_DIR=""
|
items+=("$item")
|
||||||
|
done < <(find "$dir" -mindepth 1 -maxdepth 1 -type f -name '*.md' -exec basename {} \; | sort)
|
||||||
detect_mode() {
|
|
||||||
local script_dir
|
|
||||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" || script_dir=""
|
|
||||||
|
|
||||||
if [[ -n "$script_dir" && -d "$script_dir/agents" ]]; then
|
|
||||||
MODE="local"
|
|
||||||
ASSETS_DIR="$script_dir"
|
|
||||||
elif [[ -n "$ASSETS_BASE_URL" ]]; then
|
|
||||||
MODE="remote"
|
|
||||||
else
|
else
|
||||||
fail "Set ASSETS_BASE_URL to run without a clone.
|
while IFS= read -r item; do
|
||||||
export ASSETS_BASE_URL=\"https://gitlab.com/org/repo/-/raw/develop/assets\"
|
items+=("$item")
|
||||||
bash <(curl -fsSL \"\$ASSETS_BASE_URL/setup.sh\") agents"
|
done < <(find "$dir" -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sort)
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ── Remote File Discovery ───────────────────────────────────────────
|
|
||||||
# Build the hosting platform API URL from the raw-file base URL.
|
|
||||||
# Supports GitLab and GitHub URL formats.
|
|
||||||
derive_api_url() {
|
|
||||||
local subdir="$1"
|
|
||||||
|
|
||||||
# GitLab: https://gitlab.com/<project>/-/raw/<branch>/<path>
|
|
||||||
if [[ "$ASSETS_BASE_URL" =~ ^(https?://[^/]+)/(.+)/-/raw/([^/]+)/(.+)$ ]]; then
|
|
||||||
local host="${BASH_REMATCH[1]}"
|
|
||||||
local project="${BASH_REMATCH[2]}"
|
|
||||||
local branch="${BASH_REMATCH[3]}"
|
|
||||||
local base_path="${BASH_REMATCH[4]}"
|
|
||||||
local encoded
|
|
||||||
encoded=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$project', safe=''))" 2>/dev/null) || return 1
|
|
||||||
echo "${host}/api/v4/projects/${encoded}/repository/tree?path=${base_path}/${subdir}&ref=${branch}&per_page=100"
|
|
||||||
return 0
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# GitHub: https://raw.githubusercontent.com/<owner>/<repo>/<branch>/<path>
|
if [ ${#items[@]} -eq 0 ]; then
|
||||||
if [[ "$ASSETS_BASE_URL" =~ ^https://raw\.githubusercontent\.com/([^/]+/[^/]+)/([^/]+)/(.+)$ ]]; then
|
echo "No $type found." >&2
|
||||||
local owner_repo="${BASH_REMATCH[1]}"
|
return
|
||||||
local branch="${BASH_REMATCH[2]}"
|
|
||||||
local base_path="${BASH_REMATCH[3]}"
|
|
||||||
echo "https://api.github.com/repos/${owner_repo}/contents/${base_path}/${subdir}?ref=${branch}"
|
|
||||||
return 0
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
return 1
|
echo "Available $type (${#items[@]}):" >&2
|
||||||
}
|
for i in "${!items[@]}"; do
|
||||||
|
printf " %2d) %s\n" $((i+1)) "${items[i]}" >&2
|
||||||
|
done
|
||||||
|
|
||||||
# Query the hosting API to list files in a remote directory.
|
read -r -p "Select (all / 1,3,5): " sel
|
||||||
list_remote_files() {
|
if [[ "$sel" =~ ^[Aa][Ll][Ll]$ ]] || [ -z "$sel" ]; then
|
||||||
local subdir="$1" ext="$2"
|
printf '%s\n' "${items[@]}"
|
||||||
|
|
||||||
local api_url
|
|
||||||
api_url=$(derive_api_url "$subdir") || fail "Cannot parse ASSETS_BASE_URL into an API URL.
|
|
||||||
Supported formats:
|
|
||||||
GitLab: https://gitlab.com/<project>/-/raw/<branch>/assets
|
|
||||||
GitHub: https://raw.githubusercontent.com/<owner>/<repo>/<branch>/assets"
|
|
||||||
|
|
||||||
local auth_header=""
|
|
||||||
[[ -n "$REPO_TOKEN" ]] && auth_header="Authorization: Bearer $REPO_TOKEN"
|
|
||||||
|
|
||||||
local response
|
|
||||||
response=$(curl -fsSL ${auth_header:+-H "$auth_header"} "$api_url" 2>/dev/null) \
|
|
||||||
|| fail "API request failed. If the repo is private, set REPO_TOKEN.
|
|
||||||
export REPO_TOKEN=\"glpat-...\" # GitLab personal access token
|
|
||||||
export REPO_TOKEN=\"ghp_...\" # GitHub personal access token"
|
|
||||||
|
|
||||||
# Extract filenames from JSON. Works for both GitLab and GitHub responses.
|
|
||||||
local files
|
|
||||||
files=$(echo "$response" \
|
|
||||||
| grep -o '"name":"[^"]*"' \
|
|
||||||
| sed 's/"name":"//;s/"//' \
|
|
||||||
| grep "${ext}\$" || true)
|
|
||||||
|
|
||||||
echo "$files"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ── Fetch / Download ────────────────────────────────────────────────
|
|
||||||
fetch() {
|
|
||||||
local path="$1"
|
|
||||||
if [[ "$MODE" == "local" ]]; then
|
|
||||||
cat "$ASSETS_DIR/$path"
|
|
||||||
else
|
else
|
||||||
curl -fsSL ${REPO_TOKEN:+-H "Authorization: Bearer $REPO_TOKEN"} "$ASSETS_BASE_URL/$path"
|
local selected=()
|
||||||
|
IFS=',' read -ra nums <<< "$sel"
|
||||||
|
for n in "${nums[@]}"; do
|
||||||
|
idx=$((n-1))
|
||||||
|
if (( idx >= 0 && idx < ${#items[@]} )); then
|
||||||
|
selected+=("${items[idx]}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
printf '%s\n' "${selected[@]}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
download_to() {
|
# ================== USER CHOICES ==================
|
||||||
local src="$1" dest="$2"
|
INSTALL_TYPE="${INSTALL_TYPE:-}"
|
||||||
mkdir -p "$(dirname "$dest")"
|
INSTALL_MODE="${INSTALL_MODE:-}"
|
||||||
if [[ "$MODE" == "local" ]]; then
|
if [ -z "$INSTALL_TYPE" ]; then
|
||||||
cp "$ASSETS_DIR/$src" "$dest"
|
echo "=== Step 1: What do you want to install? ==="
|
||||||
else
|
echo "1) Agents"
|
||||||
curl -fsSL ${REPO_TOKEN:+-H "Authorization: Bearer $REPO_TOKEN"} "$ASSETS_BASE_URL/$src" -o "$dest"
|
echo "2) Skills"
|
||||||
fi
|
read -r -p "Choose (1/2): " install_choice
|
||||||
}
|
case "$install_choice" in
|
||||||
|
1) INSTALL_TYPE="agents" ;;
|
||||||
# Download an entire remote directory (one level deep).
|
2) INSTALL_TYPE="skills" ;;
|
||||||
download_dir_to() {
|
*) echo "Invalid selection. Use 1 or 2."; exit 1 ;;
|
||||||
local src_subdir="$1" dest_dir="$2"
|
|
||||||
mkdir -p "$dest_dir"
|
|
||||||
if [[ "$MODE" == "local" ]]; then
|
|
||||||
cp -R "$ASSETS_DIR/$src_subdir/"* "$dest_dir/" 2>/dev/null || true
|
|
||||||
else
|
|
||||||
local files
|
|
||||||
files=$(list_remote_files "$src_subdir" "")
|
|
||||||
while IFS= read -r file; do
|
|
||||||
[[ -z "$file" ]] && continue
|
|
||||||
curl -fsSL ${REPO_TOKEN:+-H "Authorization: Bearer $REPO_TOKEN"} "$ASSETS_BASE_URL/$src_subdir/$file" -o "$dest_dir/$file"
|
|
||||||
done <<< "$files"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ── Commands ─────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# -- skills [platform] ────────────────────────────────────────────────
|
|
||||||
# 1. Install registry skills from <platform>-skills.txt
|
|
||||||
# 2. Auto-discover and copy custom skills from assets/skills/
|
|
||||||
cmd_skills() {
|
|
||||||
local platform="${1:-shared}"
|
|
||||||
local manifest="${platform}-skills.txt"
|
|
||||||
|
|
||||||
# ── Registry skills ──
|
|
||||||
heading "Registry Skills ($platform)"
|
|
||||||
|
|
||||||
local content
|
|
||||||
content="$(fetch "$manifest" 2>/dev/null)" || content=""
|
|
||||||
|
|
||||||
local reg_count=0
|
|
||||||
if [[ -n "$content" ]]; then
|
|
||||||
while IFS= read -r line; do
|
|
||||||
[[ -z "$line" || "$line" == \#* ]] && continue
|
|
||||||
info "npx skills add $line"
|
|
||||||
read -r -a args <<< "$line"
|
|
||||||
npx skills add "${args[@]}"
|
|
||||||
reg_count=$((reg_count + 1))
|
|
||||||
done <<< "$content"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $reg_count -eq 0 ]]; then
|
|
||||||
warn "No entries in $manifest."
|
|
||||||
else
|
|
||||||
ok "$reg_count registry skill(s) installed."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ── Custom / local skills ──
|
|
||||||
heading "Custom Skills → $SKILLS_DIR"
|
|
||||||
mkdir -p "$SKILLS_DIR"
|
|
||||||
|
|
||||||
local skill_dirs count=0
|
|
||||||
|
|
||||||
if [[ "$MODE" == "local" ]]; then
|
|
||||||
if [[ -d "$ASSETS_DIR/skills" ]]; then
|
|
||||||
skill_dirs=$(find "$ASSETS_DIR/skills" -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sort)
|
|
||||||
else
|
|
||||||
skill_dirs=""
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Remote: list subdirectories in skills/ via API.
|
|
||||||
# The API returns entries — filter for directories (type "tree" in GitLab, "dir" in GitHub).
|
|
||||||
local api_url
|
|
||||||
api_url=$(derive_api_url "skills") || { warn "Cannot list remote skills directories."; return 0; }
|
|
||||||
|
|
||||||
local auth_header=""
|
|
||||||
[[ -n "$REPO_TOKEN" ]] && auth_header="Authorization: Bearer $REPO_TOKEN"
|
|
||||||
|
|
||||||
local response
|
|
||||||
response=$(curl -fsSL ${auth_header:+-H "$auth_header"} "$api_url" 2>/dev/null) || { warn "Could not list remote skills."; return 0; }
|
|
||||||
|
|
||||||
# GitLab uses "type":"tree" for dirs, GitHub uses "type":"dir"
|
|
||||||
skill_dirs=$(echo "$response" \
|
|
||||||
| grep -o '"name":"[^"]*"[^}]*"type":"\(tree\|dir\)"' \
|
|
||||||
| grep -o '"name":"[^"]*"' \
|
|
||||||
| sed 's/"name":"//;s/"//' || true)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "$skill_dirs" ]]; then
|
|
||||||
warn "No custom skill folders found in assets/skills/."
|
|
||||||
else
|
|
||||||
while IFS= read -r skill; do
|
|
||||||
[[ -z "$skill" ]] && continue
|
|
||||||
info "$skill"
|
|
||||||
download_dir_to "skills/$skill" "$SKILLS_DIR/$skill"
|
|
||||||
count=$((count + 1))
|
|
||||||
done <<< "$skill_dirs"
|
|
||||||
ok "$count custom skill(s) installed."
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "\n"
|
|
||||||
ok "Restart your editor if skills don't appear."
|
|
||||||
}
|
|
||||||
|
|
||||||
# -- agents ───────────────────────────────────────────────────────────
|
|
||||||
# Discovers .agent.md files automatically (local: find, remote: API).
|
|
||||||
cmd_agents() {
|
|
||||||
heading "Agents → $AGENTS_DIR"
|
|
||||||
mkdir -p "$AGENTS_DIR"
|
|
||||||
|
|
||||||
local files count=0
|
|
||||||
|
|
||||||
if [[ "$MODE" == "local" ]]; then
|
|
||||||
files=$(find "$ASSETS_DIR/agents" -maxdepth 1 -type f -name '*.agent.md' -exec basename {} \; | sort)
|
|
||||||
else
|
|
||||||
files=$(list_remote_files "agents" ".agent.md")
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "$files" ]]; then
|
|
||||||
warn "No agent files found."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
while IFS= read -r file; do
|
|
||||||
[[ -z "$file" ]] && continue
|
|
||||||
info "$file"
|
|
||||||
download_to "agents/$file" "$AGENTS_DIR/$file"
|
|
||||||
count=$((count + 1))
|
|
||||||
done <<< "$files"
|
|
||||||
|
|
||||||
ok "$count agent(s) installed."
|
|
||||||
}
|
|
||||||
|
|
||||||
# -- instructions ─────────────────────────────────────────────────────
|
|
||||||
# Discovers .instructions.md files automatically.
|
|
||||||
cmd_instructions() {
|
|
||||||
heading "Instructions → $INSTRUCTIONS_DIR"
|
|
||||||
mkdir -p "$INSTRUCTIONS_DIR"
|
|
||||||
|
|
||||||
local files count=0
|
|
||||||
|
|
||||||
if [[ "$MODE" == "local" ]]; then
|
|
||||||
files=$(find "$ASSETS_DIR/instructions" -maxdepth 1 -type f -name '*.instructions.md' -exec basename {} \; | sort)
|
|
||||||
else
|
|
||||||
files=$(list_remote_files "instructions" ".instructions.md")
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "$files" ]]; then
|
|
||||||
warn "No instruction files found."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
while IFS= read -r file; do
|
|
||||||
[[ -z "$file" ]] && continue
|
|
||||||
info "$file"
|
|
||||||
download_to "instructions/$file" "$INSTRUCTIONS_DIR/$file"
|
|
||||||
count=$((count + 1))
|
|
||||||
done <<< "$files"
|
|
||||||
|
|
||||||
ok "$count instruction(s) installed."
|
|
||||||
}
|
|
||||||
|
|
||||||
# -- all [platform] ───────────────────────────────────────────────────
|
|
||||||
cmd_all() {
|
|
||||||
local platform="${1:-shared}"
|
|
||||||
cmd_skills "$platform"
|
|
||||||
cmd_agents
|
|
||||||
cmd_instructions
|
|
||||||
printf "\n"
|
|
||||||
ok "All done."
|
|
||||||
}
|
|
||||||
|
|
||||||
# -- help ─────────────────────────────────────────────────────────────
|
|
||||||
cmd_help() {
|
|
||||||
cat <<EOF
|
|
||||||
|
|
||||||
${BOLD}Mobile AI Assets Installer${NC} v${VERSION}
|
|
||||||
|
|
||||||
${BOLD}USAGE${NC}
|
|
||||||
setup.sh <command> [platform]
|
|
||||||
|
|
||||||
${BOLD}COMMANDS${NC}
|
|
||||||
skills [platform] Install registry + custom skills (auto-discovered)
|
|
||||||
agents Install all agent prompt files (auto-discovered)
|
|
||||||
instructions Install all instruction files (auto-discovered)
|
|
||||||
all [platform] Install everything at once
|
|
||||||
help Show this message
|
|
||||||
|
|
||||||
${BOLD}PLATFORMS${NC} (for skills)
|
|
||||||
ios iOS-specific skills
|
|
||||||
android Android-specific skills
|
|
||||||
shared Cross-platform skills (default)
|
|
||||||
|
|
||||||
${BOLD}EXAMPLES${NC}
|
|
||||||
${GREEN}# Cloned repo${NC}
|
|
||||||
./assets/setup.sh skills ios
|
|
||||||
./assets/setup.sh agents
|
|
||||||
./assets/setup.sh all ios
|
|
||||||
|
|
||||||
${GREEN}# No clone — run directly from the remote repo${NC}
|
|
||||||
export ASSETS_BASE_URL="https://gitlab.com/org/repo/-/raw/develop/assets"
|
|
||||||
bash <(curl -fsSL "\$ASSETS_BASE_URL/setup.sh") skills ios
|
|
||||||
bash <(curl -fsSL "\$ASSETS_BASE_URL/setup.sh") agents
|
|
||||||
bash <(curl -fsSL "\$ASSETS_BASE_URL/setup.sh") all ios
|
|
||||||
|
|
||||||
${BOLD}ENVIRONMENT VARIABLES${NC}
|
|
||||||
ASSETS_BASE_URL Base URL for remote downloads (required without clone)
|
|
||||||
AGENTS_DIR Install location for agents (default: ~/.agents/agents)
|
|
||||||
SKILLS_DIR Install location for custom skills (default: ~/.agents/skills)
|
|
||||||
INSTRUCTIONS_DIR Install location for instructions (default: ./instructions)
|
|
||||||
REPO_TOKEN Auth token for private repos (optional)
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# ── Main ─────────────────────────────────────────────────────────────
|
|
||||||
detect_mode
|
|
||||||
|
|
||||||
case "${1:-help}" in
|
|
||||||
skills) cmd_skills "${2:-shared}" ;;
|
|
||||||
agents) cmd_agents ;;
|
|
||||||
instructions) cmd_instructions ;;
|
|
||||||
all) cmd_all "${2:-shared}" ;;
|
|
||||||
help|--help|-h) cmd_help ;;
|
|
||||||
*) fail "Unknown command: $1. Run 'setup.sh help' for usage." ;;
|
|
||||||
esac
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\n=== Step 2: Install Mode ==="
|
||||||
|
if [ -z "$INSTALL_MODE" ]; then
|
||||||
|
echo "1) Direct copy into product folders (~/.cursor, ~/.claude, ...)"
|
||||||
|
echo "2) Global install only ($GLOBAL_ASSETS_DIR)"
|
||||||
|
echo "3) Global install + symlink into product folders"
|
||||||
|
read -r -p "Choose (1/2/3): " mode
|
||||||
|
else
|
||||||
|
mode="$INSTALL_MODE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
GLOBAL_INSTALL=false
|
||||||
|
SYMLINK_TO_PRODUCTS=false
|
||||||
|
case "$mode" in
|
||||||
|
1|direct)
|
||||||
|
GLOBAL_INSTALL=false
|
||||||
|
SYMLINK_TO_PRODUCTS=false
|
||||||
|
;;
|
||||||
|
2|global)
|
||||||
|
GLOBAL_INSTALL=true
|
||||||
|
SYMLINK_TO_PRODUCTS=false
|
||||||
|
;;
|
||||||
|
3|symlink|global+symlink|global_symlink|products)
|
||||||
|
GLOBAL_INSTALL=true
|
||||||
|
SYMLINK_TO_PRODUCTS=true
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid install mode. Use 1, 2, or 3."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$INSTALL_TYPE" = "agents" ]; then
|
||||||
|
echo -e "\n=== Step 3: Agents ==="
|
||||||
|
selected_agents=($(select_items "$AGENTS_DIR" "agents"))
|
||||||
|
selected_skills=()
|
||||||
|
elif [ "$INSTALL_TYPE" = "skills" ]; then
|
||||||
|
echo -e "\n=== Step 3: Skills ==="
|
||||||
|
selected_skills=($(select_items "$SKILLS_DIR" "skills"))
|
||||||
|
selected_agents=()
|
||||||
|
else
|
||||||
|
echo "Invalid INSTALL_TYPE: $INSTALL_TYPE (expected: agents or skills)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\n=== Step 4: Target Products ==="
|
||||||
|
for i in "${!PRODUCTS[@]}"; do
|
||||||
|
name="${PRODUCTS[i]%%:*}"
|
||||||
|
printf " %2d) %s\n" $((i+1)) "$name"
|
||||||
|
done
|
||||||
|
read -r -p "Select products (all / 1,2,4): " prod_sel
|
||||||
|
selected_products=()
|
||||||
|
if [[ "$prod_sel" =~ ^[Aa][Ll][Ll]$ ]] || [ -z "$prod_sel" ]; then
|
||||||
|
selected_products=("${PRODUCTS[@]}")
|
||||||
|
else
|
||||||
|
IFS=',' read -ra pnums <<< "$prod_sel"
|
||||||
|
for n in "${pnums[@]}"; do
|
||||||
|
idx=$((n-1))
|
||||||
|
if (( idx >= 0 && idx < ${#PRODUCTS[@]} )); then
|
||||||
|
selected_products+=("${PRODUCTS[idx]}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ================== CONFIRMATION ==================
|
||||||
|
echo -e "\n=== SUMMARY ==="
|
||||||
|
echo "Component : $INSTALL_TYPE"
|
||||||
|
if [ "$INSTALL_TYPE" = "agents" ]; then
|
||||||
|
echo "Agents : ${selected_agents[*]:-none}"
|
||||||
|
else
|
||||||
|
echo "Skills : ${selected_skills[*]:-none}"
|
||||||
|
fi
|
||||||
|
echo "Products : $(printf '%s ' "${selected_products[@]%%:*}")"
|
||||||
|
if [ "$GLOBAL_INSTALL" = false ]; then
|
||||||
|
echo "Mode : Direct to product folders"
|
||||||
|
elif [ "$SYMLINK_TO_PRODUCTS" = true ]; then
|
||||||
|
echo "Mode : Global install + product symlink"
|
||||||
|
else
|
||||||
|
echo "Mode : Global install only"
|
||||||
|
fi
|
||||||
|
echo "Global Dir : $GLOBAL_ASSETS_DIR"
|
||||||
|
echo
|
||||||
|
read -r -p "Install now? (y/N) " confirm
|
||||||
|
[[ "$confirm" =~ ^[Yy]$ ]] || { echo "Cancelled."; exit 0; }
|
||||||
|
|
||||||
|
# ================== DO THE INSTALL ==================
|
||||||
|
echo -e "\nInstalling...\n"
|
||||||
|
|
||||||
|
global_component_copied=false
|
||||||
|
|
||||||
|
for entry in "${selected_products[@]}"; do
|
||||||
|
name="${entry%%:*}"
|
||||||
|
folder="${entry#*:}"
|
||||||
|
|
||||||
|
if [ "$GLOBAL_INSTALL" = true ]; then
|
||||||
|
base_dir="$GLOBAL_ASSETS_DIR"
|
||||||
|
product_dir="$HOME/$folder"
|
||||||
|
else
|
||||||
|
base_dir="$HOME/$folder"
|
||||||
|
product_dir="$base_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$base_dir"
|
||||||
|
|
||||||
|
echo "→ $name ($folder)"
|
||||||
|
|
||||||
|
if [ "$GLOBAL_INSTALL" = false ] || [ "$global_component_copied" = false ]; then
|
||||||
|
if [ "$INSTALL_TYPE" = "agents" ]; then
|
||||||
|
for item in "${selected_agents[@]}"; do
|
||||||
|
src="$AGENTS_DIR/$item"
|
||||||
|
if [ -f "$src" ]; then
|
||||||
|
dest="$base_dir/agents/$item"
|
||||||
|
mkdir -p "$(dirname "$dest")"
|
||||||
|
cp -f "$src" "$dest"
|
||||||
|
echo " ✓ Agent: $item"
|
||||||
|
elif [ -d "$src" ]; then
|
||||||
|
dest="$base_dir/agents/$item"
|
||||||
|
rm -rf "$dest"
|
||||||
|
mkdir -p "$(dirname "$dest")"
|
||||||
|
cp -r "$src" "$dest"
|
||||||
|
echo " ✓ Agent: $item"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$INSTALL_TYPE" = "skills" ]; then
|
||||||
|
for item in "${selected_skills[@]}"; do
|
||||||
|
src="$SKILLS_DIR/$item"
|
||||||
|
if [ -d "$src" ]; then
|
||||||
|
dest="$base_dir/skills/$item"
|
||||||
|
rm -rf "$dest"
|
||||||
|
mkdir -p "$(dirname "$dest")"
|
||||||
|
cp -r "$src" "$dest"
|
||||||
|
echo " ✓ Skill: $item"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$GLOBAL_INSTALL" = true ]; then
|
||||||
|
global_component_copied=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Symlink global content into selected product folder if requested
|
||||||
|
if [ "$SYMLINK_TO_PRODUCTS" = true ]; then
|
||||||
|
mkdir -p "$product_dir"
|
||||||
|
if [ -d "$base_dir/$INSTALL_TYPE" ]; then
|
||||||
|
ln -sfn "$base_dir/$INSTALL_TYPE" "$product_dir/$INSTALL_TYPE"
|
||||||
|
echo " → Symlinked $INSTALL_TYPE into $product_dir"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "\n✅ Done! Your $INSTALL_TYPE are now available in the selected tools."
|
||||||
|
echo " Tip: git add the .cursor/, .windsurf/, etc. folders if you want to version them."
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user