commit 9623a5344f86b3843431e37f5033017ee222377e Author: vasily Date: Tue Oct 13 16:02:42 2026 +0800 Initial commit: deliver-file skill, t3-deliver, sync script diff --git a/README.md b/README.md new file mode 100644 index 0000000..80a9e6c --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# global-skills + +Personal skill repository shared by every coding agent on this host +(Antigravity/agy, Codex, OpenCode, Claude Code). Kept separate from JEV, +which remains its own project with its own skills. + +## Sources + +Agents see skills from two sources: + +| Source | Owner | Path | +|---|---|---| +| This repo | here | `~/Projects/work/global-skills/skills/` | +| JEV skills | JEV project | `~/Projects/work/JEV/.agents/skills/` | + +## Targets + +`sync-skills.sh` maintains symlinks into each agent's skills directory: + +- `~/.agents/skills` (OpenCode) +- `~/.codex/skills` (Codex) +- `~/.claude/skills` (Claude Code) + +Antigravity reads both sources directly via `~/.gemini/config/skills.json`. + +## Usage + +```sh +./sync-skills.sh # after adding/updating/removing a skill +``` + +Idempotent: re-links only what changed, never touches unrelated entries +(omarchy system skills etc.), warns on name collisions between the two +sources (this repo wins). + +## Adding a skill + +1. Create `skills//SKILL.md` with frontmatter `name` + `description`. +2. Run `./sync-skills.sh`. +3. Commit. + +## t3-deliver + +`bin/t3-deliver` is symlinked to `~/.local/bin/t3-deliver`. It prints a +ready-to-paste `scp` command (Tailscale SSH) so the user can pull any file +from this host to their Windows machine. The `deliver-file` skill teaches +every agent to use it. + +## T3 integration + +Open this folder as a project in T3 Code to get a top-bar Action running +`sync-skills.sh` (Actions are project-scoped commands). diff --git a/bin/t3-deliver b/bin/t3-deliver new file mode 100755 index 0000000..97c99e8 --- /dev/null +++ b/bin/t3-deliver @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# Print a ready-to-paste scp command for pulling a file from this host +# to the user's Windows machine over Tailscale SSH. +set -euo pipefail + +HOST="vasily@msi.tail0b014a.ts.net" + +if [[ $# -ne 1 ]]; then + echo "usage: t3-deliver " >&2 + exit 1 +fi + +path="$1" +if [[ ! -e "$path" ]]; then + echo "t3-deliver: no such path: $path" >&2 + exit 1 +fi + +if [[ "$path" != /* ]]; then + path="$(realpath "$path")" +else + path="$(realpath -m "$path")" +fi + +flags="" +if [[ -d "$path" ]]; then + flags="-r " +fi + +echo "Paste in cmd or PowerShell on your Windows machine:" +echo +echo "${flags}scp ${HOST}:\"${path}\" ." diff --git a/skills/deliver-file/SKILL.md b/skills/deliver-file/SKILL.md new file mode 100644 index 0000000..0d8f85a --- /dev/null +++ b/skills/deliver-file/SKILL.md @@ -0,0 +1,36 @@ +--- +name: deliver-file +description: > + Deliver a file or directory from this host to the user's device over + Tailscale SSH. Use when the user wants to download, receive, or get a + file, document, archive, report, or folder from the host machine. +--- + +# Deliver File + +The user's Windows machine pulls files from this host over Tailscale SSH. +Host address: `vasily@msi.tail0b014a.ts.net` (Tailscale IP 100.67.41.125). + +## Steps + +1. Resolve the absolute path of the file or directory. +2. Run `t3-deliver ` (on PATH; source: `global-skills/bin/t3-deliver`). +3. Hand the printed `scp` line to the user verbatim and note that they run + it in cmd or PowerShell on Windows. + +If `t3-deliver` is missing, print the equivalent command yourself: + +```text +scp vasily@msi.tail0b014a.ts.net:"/absolute/path/to/file" . +``` + +Add `-r` for directories. + +## Notes + +- Do not start HTTP servers or other transfer machinery for deliveries; + Tailscale SSH is the established path. +- For quick text-only needs the T3 client's "Copy contents" on an open + file also works. +- Keep generated deliverables at predictable paths and tell the user the + path when done. diff --git a/sync-skills.sh b/sync-skills.sh new file mode 100755 index 0000000..dea0e0a --- /dev/null +++ b/sync-skills.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# Sync skills from global-skills + JEV into each agent's skills directory. +# Idempotent. Never touches entries that are not managed symlinks (e.g. omarchy). +set -euo pipefail + +REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +GLOBAL_DIR="$REPO_DIR/skills" +JEV_DIR="$HOME/Projects/work/JEV/.agents/skills" +TARGETS=( + "$HOME/.agents/skills" + "$HOME/.codex/skills" + "$HOME/.claude/skills" +) + +declare -A source_of + +while IFS= read -r -d '' d; do + source_of["$(basename "$d")"]="global" +done < <(find "$GLOBAL_DIR" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null) + +while IFS= read -r -d '' d; do + name="$(basename "$d")" + if [[ -n "${source_of[$name]:-}" ]]; then + echo "WARN: collision: '$name' exists in both global-skills and JEV; using global-skills" >&2 + continue + fi + source_of["$name"]="jev" +done < <(find "$JEV_DIR" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null) + +if [[ ${#source_of[@]} -eq 0 ]]; then + echo "nothing to sync" >&2 + exit 1 +fi + +src_for() { + local name="$1" + if [[ "${source_of[$name]}" == "global" ]]; then + echo "$GLOBAL_DIR/$name" + else + echo "$JEV_DIR/$name" + fi +} + +linked=0 +skipped=0 +for target in "${TARGETS[@]}"; do + mkdir -p "$target" + for name in $(printf '%s\n' "${!source_of[@]}" | sort); do + src="$(src_for "$name")" + dest="$target/$name" + if [[ -L "$dest" ]]; then + if [[ "$(readlink -f "$dest")" == "$(readlink -f "$src")" ]]; then + continue + fi + rm "$dest" + elif [[ -e "$dest" ]]; then + echo "SKIP: $dest exists and is not a managed symlink" >&2 + skipped=$((skipped + 1)) + continue + fi + ln -s "$src" "$dest" + echo "linked: $dest -> $src" + linked=$((linked + 1)) + done +done + +echo "sync complete: $linked linked, $skipped skipped"