Merge pull request 'feat(agents-init): scaffold AGENTS/ sub-repo with symlinks, plugin dirs, and AI wrapper integration' (#52) from feat/agents-init into main
Generate documentation / build-docs (push) Successful in 37s

Reviewed-on: #52
This commit was merged in pull request #52.
This commit is contained in:
2026-06-13 04:26:24 +00:00
11 changed files with 556 additions and 69 deletions
+5
View File
@@ -288,3 +288,8 @@ poetry.toml
pyrightconfig.json pyrightconfig.json
# End of https://www.toptal.com/developers/gitignore/api/python # End of https://www.toptal.com/developers/gitignore/api/python
# ──────────────── Added by agents-init ──────────────────
# agents-init --agents
AGENTS/
# ────────────────────────────────────────────────────────
+2 -2
View File
@@ -72,8 +72,8 @@ abbr -a g git
abbr -a gitig gi abbr -a gitig gi
abbr -a git-ignore gi abbr -a git-ignore gi
# Antigravity # Antigravity
abbr -a ag antigravity abbr -a ag agy
abbr -a ag. antigravity . abbr -a ag. agy .
# Quit # Quit
abbr -a /exit exit abbr -a /exit exit
# Window-management abbreviations are opinionated (C4 integrations) # Window-management abbreviations are opinionated (C4 integrations)
+4
View File
@@ -11,6 +11,10 @@ synopsis=# SYNOPSIS
description=# DESCRIPTION description=# DESCRIPTION
toc=# TABLE OF CONTENTS toc=# TABLE OF CONTENTS
contents=# TABLE OF CONTENTS contents=# TABLE OF CONTENTS
autopair=# DESCRIPTION
puffer=# DESCRIPTION
puffer-fish=# DESCRIPTION
logging-events=# DESCRIPTION
# ── Section 1: Configuration Variables ─────────────────────── # ── Section 1: Configuration Variables ───────────────────────
variables=# 1. CONFIGURATION VARIABLES variables=# 1. CONFIGURATION VARIABLES
+41 -15
View File
@@ -43,15 +43,18 @@ The configuration is split across:
config.fish Main entry point; sets env vars and PATH config.fish Main entry point; sets env vars and PATH
conf.d/ conf.d/
abbr.fish All abbreviations abbr.fish All abbreviations
cheat.fish cheat.sh completions autopair.fish Auto-pair brackets and quotes (bundled from jorgebucaran/autopair.fish)
cheat.fish cheat.sh tab completions
done.fish Desktop notifications for long commands done.fish Desktop notifications for long commands
first_run.fish One-time init: Fisher bootstrap, theme, welcome first_run.fish One-time init: Fisher bootstrap, theme, welcome
key_bindings.fish Custom key bindings and Vi mode key_bindings.fish Custom key bindings and Vi mode
logging-events.fish C5 --on-variable event handlers; syncs logging state at startup
paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper
puffer.fish !! / !$ / ./ expansion (bundled from nickeb96/puffer-fish)
sponge_privacy.fish Sponge privacy patterns; filters credentials from history
starship.fish fish_prompt with OSC 133 shell-integration markers starship.fish fish_prompt with OSC 133 shell-integration markers
tailscale.fish Tailscale CLI tab completions tailscale.fish Tailscale CLI tab completions
theme.fish Catppuccin syntax highlight colors theme.fish Catppuccin syntax highlight colors
sponge_privacy.fish Sponge privacy patterns; filters credentials from history
tricks.fish PATH, bang-bang helpers, bat man pages, aliases tricks.fish PATH, bang-bang helpers, bat man pages, aliases
wakatime.fish WakaTime shell hook wakatime.fish WakaTime shell hook
yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper
@@ -413,8 +416,8 @@ Appending n to any :cd* abbreviation also runs nvim after changing dir.
## 4.8 AI Assistants ## 4.8 AI Assistants
ag antigravity ag agy
ag. antigravity . ag. agy .
v antigravity-ide v antigravity-ide
s wezterm ssh (WezTerm only) s wezterm ssh (WezTerm only)
@@ -1085,13 +1088,18 @@ Add -i (interactive confirmation) to destructive commands:
## 5.12 AI and Developer Tools ## 5.12 AI and Developer Tools
### antigravity ### agy
Synopsis: antigravity [args...] Synopsis: agy [args...]
Runs the agy CLI (Antigravity AI assistant) with noisy deprecation Wrapper for the agy Antigravity AI CLI. Before launching, delegates to
warnings filtered from stderr. agents-init --agents to ensure AGENTS/ is scaffolded and CLAUDE.md is
symlinked to AGENTS/AGENTS.md in the current project, then forwards all
arguments verbatim to the real agy binary. Command shadow (C1): when
__fish_config_op_aliases (or the master) is disabled, the call is
passed through to the real agy binary unchanged.
antigravity chat agy chat
agy resume
### antigravity-ide ### antigravity-ide
@@ -1105,15 +1113,33 @@ Add -i (interactive confirmation) to destructive commands:
file in the current directory, or opens an interactive fzf picker if no file in the current directory, or opens an interactive fzf picker if no
session file is found. session file is found.
### agents-init
Synopsis: agents-init [--agents | --plugins]
Scaffold an AGENTS/ sub-repository for tracking agent specs and plugin
directories. Creates AGENTS/ as a standalone git repo, initializes
standard plugin subdirectories (superpowers/, plans/, specs/), moves any
existing AGENTS.md and docs/plugin dirs into the sub-repo, and replaces
them with relative symlinks. Also adds CLAUDE.md -> AGENTS/AGENTS.md so
Claude Code picks up the shared agent instructions. Adds all managed
paths to .gitignore and auto-commits every change inside the AGENTS/
sub-repo. Fully idempotent: a second run produces no output and no new
commits. Flags: --agents re-runs only the AGENTS.md / symlink step;
--plugins re-runs only the plugin-directory wiring step. Called
automatically by the claude and agy wrappers on every invocation.
agents-init
agents-init --agents
agents-init --plugins
### claude ### claude
Synopsis: claude [args...] Synopsis: claude [args...]
Wrapper for the claude CLI. Before launching, checks the current Wrapper for the claude CLI. Before launching, delegates to agents-init
directory and the git project root for CLAUDE.md; when it is absent but --agents to ensure AGENTS/ is scaffolded and CLAUDE.md is symlinked to
AGENTS.md is present, creates a relative symlink CLAUDE.md -> AGENTS.md AGENTS/AGENTS.md in the current project, then forwards all arguments
so Claude Code picks up shared agent instructions without duplicating verbatim to the real claude binary. Command shadow (C1): when
the file. All arguments are forwarded verbatim. Command shadow (C1): __fish_config_op_aliases (or the master) is disabled, the call is
when __fish_config_op_aliases (or the master) is disabled, the call is
passed through to the real claude binary unchanged. passed through to the real claude binary unchanged.
claude claude
@@ -0,0 +1,82 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# _agents_init_ensure_gitignore <root> <label> <pattern>...
#
# DESCRIPTION
# Appends any patterns not already covered by the project's .gitignore.
# Uses `git check-ignore` for accurate rule matching (catches wildcards
# and parent-dir globs). Falls back to a plain string search when the
# root is not a git repository. Leading `/` is stripped from each pattern
# before the path-based check so root-anchored patterns (e.g. /AGENTS.md)
# are matched correctly.
#
# Missing patterns are written as a single labeled block:
#
# # ──────────────── Added by agents-init ──────────────────
# # <label>
# <pattern>
# # ────────────────────────────────────────────────────────
#
# ARGUMENTS
# root Absolute path to the project root containing .gitignore
# label Short description used in the block comment header
# pattern One or more gitignore patterns to ensure are present
#
# RETURNS
# 0 All patterns already ignored or successfully appended
# 1 Could not write to .gitignore
#
# EXAMPLE
# _agents_init_ensure_gitignore /home/user/myproject "agents-init" "AGENTS/" "/AGENTS.md"
function _agents_init_ensure_gitignore
set -l c_ok (set_color green)
set -l c_reset (set_color normal)
if test (count $argv) -lt 3
echo (set_color red)"_agents_init_ensure_gitignore: requires <root> <label> <pattern>..."(set_color normal) >&2
return 1
end
set -l root $argv[1]
set -l label $argv[2]
set -l patterns $argv[3..]
set -l gitignore "$root/.gitignore"
set -l in_git 0
git -C "$root" rev-parse --git-dir >/dev/null 2>&1
and set in_git 1
# Collect patterns not already covered
set -l missing
for pattern in $patterns
# Strip leading / so git check-ignore receives a repo-relative path,
# not an absolute filesystem path (which it cannot match against rules).
set -l check_path (string replace -r '^/' '' "$pattern")
set -l already 0
if test $in_git -eq 1
git -C "$root" check-ignore -q --no-index "$check_path" 2>/dev/null
and set already 1
else if test -f "$gitignore"
grep -qF "$pattern" "$gitignore"
and set already 1
end
if test $already -eq 0
set -a missing "$pattern"
end
end
test (count $missing) -eq 0; and return 0
# Write missing patterns as a labeled block
set -l header "# ──────────────── Added by agents-init ──────────────────"
set -l footer "# ────────────────────────────────────────────────────────"
printf '\n%s\n# %s\n' "$header" "$label" >>"$gitignore"
for p in $missing
printf '%s\n' "$p" >>"$gitignore"
end
printf '%s\n' "$footer" >>"$gitignore"
echo "$c_ok→ Added "(count $missing)" pattern(s) to .gitignore$c_reset"
end
+337
View File
@@ -0,0 +1,337 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# agents-init [-a | --agents] [-p | --plugins] [-v | --verbose]
# [-q | --quiet] [-s | --silent] [-h | --help]
#
# DESCRIPTION
# Scaffolds an AGENTS/ sub-repository inside a project directory. Creates
# a self-contained git repo for agent specifications, moves any existing
# agent-related files into it, and replaces them with symlinks so the outer
# project never tracks agent files directly.
#
# File layout after setup:
# AGENTS/AGENTS.md canonical agent spec (real file)
# AGENTS/CLAUDE.md real file (if CLAUDE.md existed separately)
# or symlink → AGENTS.md (single-source case)
# <root>/AGENTS.md → AGENTS/AGENTS.md
# <root>/CLAUDE.md → AGENTS/CLAUDE.md
# docs/<plug> → ../AGENTS/plugins/<plug>
#
# With no flags, runs both --agents and --plugins setup. At the end of
# every invocation, commits any uncommitted changes in the AGENTS/ sub-repo
# so that agent-made edits are captured automatically.
#
# ARGUMENTS
# -a, --agents Set up AGENTS/ repo + AGENTS.md / CLAUDE.md symlinks only
# -p, --plugins Set up AGENTS/ repo + plugins dirs + docs/ symlinks only
# -v, --verbose Print all per-step output (default)
# -q, --quiet Print one summary line only if changes were made
# -s, --silent Suppress all output; errors only (standard UNIX convention)
# -h, --help Show this help message and exit
#
# RETURNS
# 0 Setup completed successfully
# 1 Fatal error (git init failed, move failed, etc.)
#
# EXAMPLE
# agents-init
# agents-init --agents
# agents-init --plugins
# agents-init --quiet
function agents-init --description 'scaffold AGENTS/ sub-repo with agent spec files and plugin dirs'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold white)
set -l c_flag (set_color yellow)
set -l c_ok (set_color green)
set -l c_warn (set_color yellow)
set -l c_dim (set_color brblack)
set -l c_err (set_color red)
set -l c_reset (set_color normal)
argparse h/help a/agents p/plugins v/verbose q/quiet s/silent -- $argv
or return 1
if set -q _flag_help
echo "$c_head""Usage:$c_reset $c_cmd""agents-init$c_reset $c_flag""[-a] [-p] [-v] [-q] [-s] [-h | --help]$c_reset"
echo
echo " Scaffold an AGENTS/ sub-repository for tracking agent specifications."
echo
echo "$c_head""Options:$c_reset"
echo " $c_flag-h$c_reset, $c_flag--help$c_reset Show this help message"
echo " $c_flag-a$c_reset, $c_flag--agents$c_reset Set up AGENTS.md / CLAUDE.md symlinks only"
echo " $c_flag-p$c_reset, $c_flag--plugins$c_reset Set up plugins dirs and docs/ symlinks only"
echo " $c_flag-v$c_reset, $c_flag--verbose$c_reset Print all per-step output (default)"
echo " $c_flag-q$c_reset, $c_flag--quiet$c_reset Print one summary line only if changes were made"
echo " $c_flag-s$c_reset, $c_flag--silent$c_reset Suppress all output; only errors are printed"
echo " $c_dim(no flags)$c_reset Run both --agents and --plugins setup"
return 0
end
# No flags → run both modes
set -l do_agents 0
set -l do_plugins 0
set -q _flag_agents; and set do_agents 1
set -q _flag_plugins; and set do_plugins 1
if test $do_agents -eq 0; and test $do_plugins -eq 0
set do_agents 1
set do_plugins 1
end
# Output verbosity: verbose (default), quiet (summary if changed), silent (errors only)
set -l verbose 1
set -l quiet 0
if set -q _flag_silent
set verbose 0
else if set -q _flag_quiet
set verbose 0
set quiet 1
end
# --verbose is explicit default; no-op but accepted for completeness
# Resolve target root: git root if available, otherwise cwd
set -l root (git rev-parse --show-toplevel 2>/dev/null)
test -z "$root"; and set root (pwd)
set -l agents_dir "$root/AGENTS"
set -l plugins_dir "$agents_dir/plugins"
# Track whether any action was taken this run (drives quiet-mode summary)
set -l changed 0
# ─────────────────────── Always: AGENTS/ sub-repo ───────────────────────
set -l did_init 0
if not test -d "$agents_dir"
if not mkdir -p "$agents_dir"
echo "$c_err""Error: could not create AGENTS/$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Created AGENTS/$c_reset"
end
if not test -d "$agents_dir/.git"
git -C "$agents_dir" init -q
or begin
echo "$c_err""Error: git init failed in AGENTS/$c_reset" >&2
return 1
end
set changed 1
set did_init 1
test $verbose -eq 1; and echo "$c_ok→ Initialized git repo in AGENTS/$c_reset"
end
# ──────────────────────────── --agents mode ──────────────────────────────
if test $do_agents -eq 1
# Detect which root-level files are real (not symlinks)
set -l has_agents 0
set -l has_claude 0
if test -f "$root/AGENTS.md"; and not test -L "$root/AGENTS.md"
set has_agents 1
end
if test -f "$root/CLAUDE.md"; and not test -L "$root/CLAUDE.md"
set has_claude 1
end
# ── Move real files into AGENTS/ ──────────────────────────────────────
if test $has_agents -eq 1; and test $has_claude -eq 1
# Both exist: preserve each as its own file in AGENTS/
if not test -f "$agents_dir/AGENTS.md"
if not mv "$root/AGENTS.md" "$agents_dir/AGENTS.md"
echo "$c_err""Error: could not move AGENTS.md → AGENTS/AGENTS.md$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Moved AGENTS.md → AGENTS/AGENTS.md$c_reset"
end
if not test -f "$agents_dir/CLAUDE.md"; and not test -L "$agents_dir/CLAUDE.md"
if not mv "$root/CLAUDE.md" "$agents_dir/CLAUDE.md"
echo "$c_err""Error: could not move CLAUDE.md → AGENTS/CLAUDE.md$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Moved CLAUDE.md → AGENTS/CLAUDE.md$c_reset"
end
else if test $has_agents -eq 1
if not test -f "$agents_dir/AGENTS.md"
if not mv "$root/AGENTS.md" "$agents_dir/AGENTS.md"
echo "$c_err""Error: could not move AGENTS.md → AGENTS/AGENTS.md$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Moved AGENTS.md → AGENTS/AGENTS.md$c_reset"
end
else if test $has_claude -eq 1
# Only CLAUDE.md: treat it as the agent spec
if not test -f "$agents_dir/AGENTS.md"
if not mv "$root/CLAUDE.md" "$agents_dir/AGENTS.md"
echo "$c_err""Error: could not move CLAUDE.md → AGENTS/AGENTS.md$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Moved CLAUDE.md → AGENTS/AGENTS.md$c_reset"
end
else
# Neither exists: create AGENTS/AGENTS.md with the agent directive
if not test -f "$agents_dir/AGENTS.md"
printf '%s\n' \
'# AGENTS.md' \
'' \
'> ⚠️ **SYSTEM DIRECTIVE FOR AI AGENTS: FILE EDITING**' \
'> You may be reading this file via a symlink (`CLAUDE.md` or `AGENTS.md`) in' \
'> the root of the project. Your environment'\''s file-editing tools cannot write' \
'> through symlinks and will throw an error.' \
'>' \
'> **DO NOT** attempt to write to or edit `CLAUDE.md` or `AGENTS.md` in the' \
'> project root. If you need to update these instructions, you **MUST write' \
'> directly to `AGENTS/AGENTS.md`**.' >"$agents_dir/AGENTS.md"
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Created AGENTS/AGENTS.md with agent directive$c_reset"
end
end
# ── Ensure AGENTS/CLAUDE.md exists ────────────────────────────────────
# When both files existed, AGENTS/CLAUDE.md is already a real file.
# Otherwise, create it as a symlink → AGENTS.md (within AGENTS/).
if not test -f "$agents_dir/CLAUDE.md"; and not test -L "$agents_dir/CLAUDE.md"
if not ln -s AGENTS.md "$agents_dir/CLAUDE.md"
echo "$c_err""Error: could not create AGENTS/CLAUDE.md symlink$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Linked AGENTS/CLAUDE.md → AGENTS/AGENTS.md$c_reset"
end
# ── Root symlink: AGENTS.md → AGENTS/AGENTS.md ───────────────────────
set -l _need_link 0
if not test -L "$root/AGENTS.md"
set _need_link 1
else if test (readlink "$root/AGENTS.md") != AGENTS/AGENTS.md
rm -f "$root/AGENTS.md"
set _need_link 1
end
if test $_need_link -eq 1
if not ln -s AGENTS/AGENTS.md "$root/AGENTS.md"
echo "$c_err""Error: could not create AGENTS.md symlink$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Linked AGENTS.md → AGENTS/AGENTS.md$c_reset"
end
# ── Root symlink: CLAUDE.md → AGENTS/CLAUDE.md ───────────────────────
set -l _need_link 0
if not test -L "$root/CLAUDE.md"
set _need_link 1
else if test (readlink "$root/CLAUDE.md") != AGENTS/CLAUDE.md
rm -f "$root/CLAUDE.md"
set _need_link 1
end
if test $_need_link -eq 1
if not ln -s AGENTS/CLAUDE.md "$root/CLAUDE.md"
echo "$c_err""Error: could not create CLAUDE.md symlink$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Linked CLAUDE.md → AGENTS/CLAUDE.md$c_reset"
end
# ── .gitignore ────────────────────────────────────────────────────────
set -l _gi (_agents_init_ensure_gitignore "$root" "agents-init --agents" "AGENTS/" "/AGENTS.md" "/CLAUDE.md")
if test -n "$_gi"
set changed 1
test $verbose -eq 1; and echo $_gi
end
end
# ─────────────────────────── --plugins mode ──────────────────────────────
if test $do_plugins -eq 1
# Ensure AGENTS/plugins/ dirs exist with .gitkeep
for dir in "$plugins_dir" "$plugins_dir/superpowers" "$plugins_dir/plans" "$plugins_dir/specs"
if not test -d "$dir"
if not mkdir -p "$dir"
echo "$c_err""Error: could not create "(string replace "$root/" "" "$dir")"/$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Created "(string replace "$root/" "" "$dir")"/$c_reset"
end
test -f "$dir/.gitkeep"; or touch "$dir/.gitkeep"
end
set -l docs_dir "$root/docs"
if not test -d "$docs_dir"
if not mkdir -p "$docs_dir"
echo "$c_err""Error: could not create docs/$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Created docs/$c_reset"
end
for plug in superpowers plans specs
set -l docs_target "$docs_dir/$plug"
set -l agents_target "$plugins_dir/$plug"
# If a real directory exists in docs/, migrate its contents to AGENTS/plugins/
if test -d "$docs_target"; and not test -L "$docs_target"
set -l contents (ls -A "$docs_target" 2>/dev/null)
if test (count $contents) -gt 0
if not command cp -rn "$docs_target/." "$agents_target/"
echo "$c_err""Error: could not copy docs/$plug → AGENTS/plugins/$plug$c_reset" >&2
return 1
end
end
if not rm -rf "$docs_target"
echo "$c_err""Error: could not remove docs/$plug after copy$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Moved docs/$plug → AGENTS/plugins/$plug$c_reset"
end
# Create symlink docs/<plug> → ../AGENTS/plugins/<plug>
if not test -L "$docs_target"
if not ln -s "../AGENTS/plugins/$plug" "$docs_target"
echo "$c_err""Error: could not create docs/$plug symlink$c_reset" >&2
return 1
end
set changed 1
test $verbose -eq 1; and echo "$c_ok→ Linked docs/$plug → AGENTS/plugins/$plug$c_reset"
end
end
set -l _gi (_agents_init_ensure_gitignore "$root" "agents-init --plugins" "docs/superpowers" "docs/plans" "docs/specs")
if test -n "$_gi"
set changed 1
test $verbose -eq 1; and echo $_gi
end
end
# ──────────────────────── Auto-commit AGENTS/ ────────────────────────────
git -C "$agents_dir" add -A 2>/dev/null
set -l status_out (git -C "$agents_dir" status --porcelain 2>/dev/null)
if test -n "$status_out"
set -l msg "chore: sync AGENTS repository"
test $did_init -eq 1; and set msg "chore: initialize AGENTS repository"
if git -C "$agents_dir" -c commit.gpgsign=false commit -q -m "$msg" 2>/dev/null
set changed 1
if test $verbose -eq 1
set -l sha (git -C "$agents_dir" rev-parse --short HEAD 2>/dev/null)
echo "$c_ok→ Committed AGENTS/ ($sha) $c_dim$msg$c_reset"
end
end
end
# Quiet summary: one line at the end, only if something actually changed
if test $quiet -eq 1; and test $changed -eq 1
if test $did_init -eq 1
echo "$c_ok→ Initialized AGENTS scaffolding$c_reset"
else
echo "$c_ok→ Synced AGENTS scaffolding$c_reset"
end
end
end
+36
View File
@@ -0,0 +1,36 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# agy [ARGS...]
#
# DESCRIPTION
# Wrapper for the agy Antigravity AI CLI that ensures the AGENTS/
# sub-repository is initialized and any agent-made changes are committed
# before launch. Delegates all scaffold and commit logic to agents-init
# (full setup). All arguments are forwarded verbatim to the real agy binary.
#
# Opinionated component (C1): when disabled via __fish_config_op_aliases
# (or the __fish_config_opinionated master), the command is passed through
# to the real agy binary unchanged.
#
# ARGUMENTS
# ARGS Any arguments forwarded verbatim to the underlying agy binary
#
# RETURNS
# Exit status of the underlying agy binary
#
# EXAMPLE
# agy
# agy chat
# agy resume
function agy --wraps=agy --description 'agy wrapper: auto-initializes AGENTS/ sub-repo before launch'
if not __fish_config_op_enabled __fish_config_op_aliases
command agy $argv
return $status
end
agents-init --quiet
command agy $argv
end
-19
View File
@@ -1,19 +0,0 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# antigravity [args...]
#
# DESCRIPTION
# Wrapper for the agy Antigravity AI CLI that filters a known noisy warning
# about an unrecognized 'app' option from stderr.
#
# ARGUMENTS
# args... Arguments passed through to the agy command
#
# EXAMPLE
# antigravity chat
function antigravity --wraps='agy' --description 'alias antigravity=agy'
# In fish, we pipe stderr using '2>|' to another command
command agy $argv 2>| grep -v "'app' is not in the list of known options" >&2
end
+5 -33
View File
@@ -5,12 +5,10 @@
# claude [ARGS...] # claude [ARGS...]
# #
# DESCRIPTION # DESCRIPTION
# Wrapper for the claude CLI that ensures CLAUDE.md exists before launch. # Wrapper for the claude CLI that ensures the AGENTS/ sub-repository is
# Both the current directory and the git project root are checked. When # initialized and any agent-made changes are committed before launch.
# CLAUDE.md is absent but AGENTS.md is present in a checked directory, a # Delegates all scaffold and commit logic to agents-init (full setup).
# relative symlink CLAUDE.md -> AGENTS.md is created automatically so that # All arguments are forwarded verbatim to the real claude binary.
# Claude Code picks up shared agent instructions without duplicating the
# file. All arguments are forwarded verbatim to the real claude binary.
# #
# Opinionated component (C1): when disabled via __fish_config_op_aliases # Opinionated component (C1): when disabled via __fish_config_op_aliases
# (or the __fish_config_opinionated master), the command is passed through # (or the __fish_config_opinionated master), the command is passed through
@@ -32,33 +30,7 @@ function claude --wraps=claude --description 'claude wrapper: auto-links AGENTS.
return $status return $status
end end
set -l c_ok (set_color green) agents-init --quiet
set -l c_reset (set_color normal)
# Build the list of directories to inspect: cwd always, git root when different.
set -l check_dirs (pwd)
set -l git_root (git rev-parse --show-toplevel 2>/dev/null)
if test -n "$git_root" -a "$git_root" != (pwd)
set check_dirs $check_dirs $git_root
end
# Anchor for relative display: git root when available, otherwise cwd.
set -l anchor $git_root
test -z "$anchor" && set anchor (pwd)
for dir in $check_dirs
if not test -e "$dir/CLAUDE.md"
if test -f "$dir/AGENTS.md"
ln -s AGENTS.md "$dir/CLAUDE.md"
set -l prefix ""
if test "$dir" != "$anchor"
set prefix (string replace "$anchor/" "" "$dir")/
end
set -l msg (string join "" "→ Linked " $prefix "CLAUDE.md → " $prefix "AGENTS.md")
echo $c_ok$msg$c_reset >&2
end
end
end
command claude $argv command claude $argv
end end
+22
View File
@@ -3,6 +3,28 @@
# Copyright (C) 2026 Rootiest # Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# Invoked as an Antigravity session hook; reads JSON from stdin.
#
# DESCRIPTION
# Hook script called by the Antigravity CLI (agy) on session start.
# Reads a JSON payload from stdin, extracts the session_id field, and
# writes it to .antigravity_session in the current directory. Ensures
# that file is excluded via .gitignore. Sets the universal variable
# LAST_ANTIGRAVITY_SESSION for cross-terminal access. Falls back to a
# no-op (emitting "{}") when python3 is unavailable (Convention §6).
#
# ARGUMENTS
# stdin JSON payload from the Antigravity CLI containing a "session_id" key
#
# RETURNS
# 0 Always; emits "{}" to stdout as required by the hook contract
#
# EXAMPLE
# echo '{"session_id":"abc123"}' | fish save_antigravity_session.fish
# cat .antigravity_session # → abc123
# echo $LAST_ANTIGRAVITY_SESSION # → abc123
# 1. Read the JSON from stdin # 1. Read the JSON from stdin
set -l input (cat) set -l input (cat)
+22
View File
@@ -3,6 +3,28 @@
# Copyright (C) 2026 Rootiest # Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# Invoked as a Claude Code session hook; reads JSON from stdin.
#
# DESCRIPTION
# Hook script called by Claude Code on session start. Reads a JSON payload
# from stdin, extracts the session_id field, and writes it to .claude_session
# in the current directory. Ensures that file is excluded via .gitignore.
# Sets the universal variable LAST_CLAUDE_SESSION for cross-terminal access.
# Falls back to a no-op (emitting "{}") when python3 is unavailable
# (Convention §6).
#
# ARGUMENTS
# stdin JSON payload from Claude Code containing a "session_id" key
#
# RETURNS
# 0 Always; emits "{}" to stdout as required by the hook contract
#
# EXAMPLE
# echo '{"session_id":"abc123"}' | fish save_claude_session.fish
# cat .claude_session # → abc123
# echo $LAST_CLAUDE_SESSION # → abc123
# 1. Read input and extract session ID # 1. Read input and extract session ID
# python3 parses the session_id out of the hook's JSON payload. If it is # python3 parses the session_id out of the hook's JSON payload. If it is
# unavailable we emit valid empty JSON and skip session tracking rather # unavailable we emit valid empty JSON and skip session tracking rather