Initial commit: deliver-file skill, t3-deliver, sync script
This commit is contained in:
commit
9623a5344f
4 files changed
+187
No files matched your search
@@ -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-name>/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).
|
||||||
Executable
+32
@@ -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 <file-or-directory>" >&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}\" ."
|
||||||
@@ -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 <path>` (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.
|
||||||
Executable
+67
@@ -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"
|
||||||
Reference in new issue
Block a user