232 lines
5.9 KiB
Bash
Executable File
232 lines
5.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# mosaic — Unified agent launcher and management CLI
|
|
#
|
|
# AGENTS.md is the single source of truth for all agent sessions.
|
|
# The launcher injects it into every runtime consistently.
|
|
#
|
|
# Usage:
|
|
# mosaic claude [args...] Launch Claude Code with AGENTS.md injected
|
|
# mosaic opencode [args...] Launch OpenCode with AGENTS.md injected
|
|
# mosaic codex [args...] Launch Codex with AGENTS.md injected
|
|
# mosaic init [args...] Generate SOUL.md interactively
|
|
# mosaic doctor [args...] Health audit
|
|
# mosaic sync [args...] Sync skills
|
|
# mosaic bootstrap <path> Bootstrap a repo
|
|
# mosaic upgrade release Upgrade installed Mosaic release
|
|
# mosaic upgrade check Check release upgrade status (no changes)
|
|
# mosaic upgrade project [args] Upgrade project-local stale files
|
|
|
|
MOSAIC_HOME="${MOSAIC_HOME:-$HOME/.config/mosaic}"
|
|
VERSION="0.1.0"
|
|
|
|
usage() {
|
|
cat <<USAGE
|
|
mosaic $VERSION — Unified agent launcher
|
|
|
|
Usage: mosaic <command> [args...]
|
|
|
|
Agent Launchers:
|
|
claude [args...] Launch Claude Code with AGENTS.md injected
|
|
opencode [args...] Launch OpenCode with AGENTS.md injected
|
|
codex [args...] Launch Codex with AGENTS.md injected
|
|
|
|
Management:
|
|
init [args...] Generate SOUL.md (agent identity contract)
|
|
doctor [args...] Audit runtime state and detect drift
|
|
sync [args...] Sync skills from canonical source
|
|
bootstrap <path> Bootstrap a repo with Mosaic standards
|
|
upgrade [mode] [args] Upgrade release (default) or project files
|
|
upgrade check Check release upgrade status (no changes)
|
|
release-upgrade [...] Upgrade installed Mosaic release
|
|
project-upgrade [...] Clean up stale SOUL.md/CLAUDE.md in a project
|
|
|
|
Options:
|
|
-h, --help Show this help
|
|
-v, --version Show version
|
|
|
|
All arguments after the command are forwarded to the target CLI.
|
|
USAGE
|
|
}
|
|
|
|
# Pre-flight checks
|
|
check_mosaic_home() {
|
|
if [[ ! -d "$MOSAIC_HOME" ]]; then
|
|
echo "[mosaic] ERROR: ~/.config/mosaic not found." >&2
|
|
echo "[mosaic] Install with: curl -sL https://git.mosaicstack.dev/mosaic/bootstrap/raw/branch/main/remote-install.sh | sh" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_agents_md() {
|
|
if [[ ! -f "$MOSAIC_HOME/AGENTS.md" ]]; then
|
|
echo "[mosaic] ERROR: ~/.config/mosaic/AGENTS.md not found." >&2
|
|
echo "[mosaic] Re-run the installer: cd ~/src/mosaic-bootstrap && bash install.sh" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_soul() {
|
|
if [[ ! -f "$MOSAIC_HOME/SOUL.md" ]]; then
|
|
echo "[mosaic] SOUL.md not found. Running mosaic init..."
|
|
"$MOSAIC_HOME/bin/mosaic-init"
|
|
fi
|
|
}
|
|
|
|
check_runtime() {
|
|
local cmd="$1"
|
|
if ! command -v "$cmd" >/dev/null 2>&1; then
|
|
echo "[mosaic] ERROR: '$cmd' not found in PATH." >&2
|
|
echo "[mosaic] Install $cmd before launching." >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Ensure AGENTS.md is present at the runtime's native config path.
|
|
# Used for runtimes that don't support CLI prompt injection.
|
|
ensure_runtime_config() {
|
|
local src="$MOSAIC_HOME/AGENTS.md"
|
|
local dst="$1"
|
|
mkdir -p "$(dirname "$dst")"
|
|
if ! cmp -s "$src" "$dst" 2>/dev/null; then
|
|
cp "$src" "$dst"
|
|
fi
|
|
}
|
|
|
|
# Launcher functions
|
|
launch_claude() {
|
|
check_mosaic_home
|
|
check_agents_md
|
|
check_soul
|
|
check_runtime "claude"
|
|
|
|
# Claude supports --append-system-prompt for direct injection
|
|
local agents_content
|
|
agents_content="$(cat "$MOSAIC_HOME/AGENTS.md")"
|
|
echo "[mosaic] Launching Claude Code..."
|
|
exec claude --append-system-prompt "$agents_content" "$@"
|
|
}
|
|
|
|
launch_opencode() {
|
|
check_mosaic_home
|
|
check_agents_md
|
|
check_soul
|
|
check_runtime "opencode"
|
|
|
|
# OpenCode reads from ~/.config/opencode/AGENTS.md — copy canonical version there
|
|
ensure_runtime_config "$HOME/.config/opencode/AGENTS.md"
|
|
echo "[mosaic] Launching OpenCode..."
|
|
exec opencode "$@"
|
|
}
|
|
|
|
launch_codex() {
|
|
check_mosaic_home
|
|
check_agents_md
|
|
check_soul
|
|
check_runtime "codex"
|
|
|
|
# Codex reads from ~/.codex/instructions.md — copy canonical version there
|
|
ensure_runtime_config "$HOME/.codex/instructions.md"
|
|
echo "[mosaic] Launching Codex..."
|
|
exec codex "$@"
|
|
}
|
|
|
|
# Delegate to existing scripts
|
|
run_init() {
|
|
check_mosaic_home
|
|
exec "$MOSAIC_HOME/bin/mosaic-init" "$@"
|
|
}
|
|
|
|
run_doctor() {
|
|
check_mosaic_home
|
|
exec "$MOSAIC_HOME/bin/mosaic-doctor" "$@"
|
|
}
|
|
|
|
run_sync() {
|
|
check_mosaic_home
|
|
exec "$MOSAIC_HOME/bin/mosaic-sync-skills" "$@"
|
|
}
|
|
|
|
run_bootstrap() {
|
|
check_mosaic_home
|
|
exec "$MOSAIC_HOME/bin/mosaic-bootstrap-repo" "$@"
|
|
}
|
|
|
|
run_release_upgrade() {
|
|
check_mosaic_home
|
|
exec "$MOSAIC_HOME/bin/mosaic-release-upgrade" "$@"
|
|
}
|
|
|
|
run_project_upgrade() {
|
|
check_mosaic_home
|
|
exec "$MOSAIC_HOME/bin/mosaic-upgrade" "$@"
|
|
}
|
|
|
|
run_upgrade() {
|
|
check_mosaic_home
|
|
|
|
# Default: upgrade installed release
|
|
if [[ $# -eq 0 ]]; then
|
|
run_release_upgrade
|
|
fi
|
|
|
|
case "$1" in
|
|
release)
|
|
shift
|
|
run_release_upgrade "$@"
|
|
;;
|
|
check)
|
|
shift
|
|
run_release_upgrade --dry-run "$@"
|
|
;;
|
|
project)
|
|
shift
|
|
run_project_upgrade "$@"
|
|
;;
|
|
|
|
# Backward compatibility for historical project-upgrade usage.
|
|
--all|--root)
|
|
run_project_upgrade "$@"
|
|
;;
|
|
--dry-run|--ref|--keep|--overwrite|-y|--yes)
|
|
run_release_upgrade "$@"
|
|
;;
|
|
-*)
|
|
run_release_upgrade "$@"
|
|
;;
|
|
*)
|
|
run_project_upgrade "$@"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Main router
|
|
if [[ $# -eq 0 ]]; then
|
|
usage
|
|
exit 0
|
|
fi
|
|
|
|
command="$1"
|
|
shift
|
|
|
|
case "$command" in
|
|
claude) launch_claude "$@" ;;
|
|
opencode) launch_opencode "$@" ;;
|
|
codex) launch_codex "$@" ;;
|
|
init) run_init "$@" ;;
|
|
doctor) run_doctor "$@" ;;
|
|
sync) run_sync "$@" ;;
|
|
bootstrap) run_bootstrap "$@" ;;
|
|
upgrade) run_upgrade "$@" ;;
|
|
release-upgrade) run_release_upgrade "$@" ;;
|
|
project-upgrade) run_project_upgrade "$@" ;;
|
|
help|-h|--help) usage ;;
|
|
version|-v|--version) echo "mosaic $VERSION" ;;
|
|
*)
|
|
echo "[mosaic] Unknown command: $command" >&2
|
|
echo "[mosaic] Run 'mosaic --help' for usage." >&2
|
|
exit 1
|
|
;;
|
|
esac
|