#!/bin/sh # Install TypeFuse for Claude Code and Codex: https://typefuse.dev/agents # # curl -fsSL https://typefuse.dev/install | sh # every agent it finds # curl -fsSL https://typefuse.dev/install | sh -s -- --codex # choose: --claude, --codex # TYPEFUSE_TOKEN=tf_pat_... sh install # CI: the tools use an access token # # It writes only the skill (~/.claude/skills/typefuse, ~/.codex/skills/typefuse) and runs # `claude mcp add` and `codex mcp add` to give each agent the TypeFuse tools. No sudo. # Run it again to update the skill: it replaces only the skill's files and keeps the TypeFuse tools. set -eu APP='https://typefuse.dev' MCP='https://api.typefuse.dev/v1/mcp' SKILL_VERSION='0.3.6' say() { printf '%s\n' "$*"; } fail() { printf 'typefuse: %s\n' "$*" >&2; exit 1; } do_claude=no do_codex=no chosen=no for arg in "$@"; do case "$arg" in --claude|--claude-code) do_claude=yes; chosen=yes ;; --codex) do_codex=yes; chosen=yes ;; -h|--help) say "Usage: sh install [--claude] [--codex]"; exit 0 ;; *) fail "unknown option $arg (use --claude or --codex)" ;; esac done if [ "$chosen" = no ]; then if command -v claude >/dev/null 2>&1 || [ -d "$HOME/.claude" ]; then do_claude=yes; fi if command -v codex >/dev/null 2>&1 || [ -d "$HOME/.codex" ]; then do_codex=yes; fi [ "$do_claude" = yes ] || [ "$do_codex" = yes ] || fail "found neither Claude Code nor Codex; install one, or choose with --claude or --codex" fi command -v curl >/dev/null 2>&1 || fail "curl is needed" install_skill() { # $1: ~/.claude or ~/.codex; $2: the option that chooses it (--claude or --codex) skills="$1/skills" dir="$skills/typefuse" new="$skills/.typefuse-new" old="$skills/.typefuse-old" mkdir -p "$skills" # A complete clean copy is made beside the skill, then swapped in, so a re-run leaves no stale file. rm -rf "$new" "$old" mkdir "$new" curl -fsSL "$APP/agents/typefuse/SKILL.md" -o "$new/SKILL.md" # The version and the exact command, so an update reinstalls for the same agent. printf '{\n "version": "%s",\n "source": "%s",\n "agent": "%s",\n "command": "%s",\n "installed_at": "%s"\n}\n' \ "$SKILL_VERSION" "$APP/install" "${2#--}" "curl -fsSL $APP/install | sh -s -- $2" \ "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$new/.typefuse-skill.json" if [ -d "$dir" ]; then mv "$dir" "$old"; fi mv "$new" "$dir" rm -rf "$old" say "Installed the TypeFuse skill $SKILL_VERSION in $dir" } # What happened to each agent's TypeFuse tools, for the Next steps: yes (added, or already there), # missing (its command isn't on the PATH), pending (waiting for an access token) or no (not chosen). claude_tools=no codex_tools=no add_claude_tools() { if ! command -v claude >/dev/null 2>&1; then say "Claude Code: the claude command isn't on your PATH, so the TypeFuse tools weren't added." claude_tools=missing return 0 fi if claude mcp get typefuse >/dev/null 2>&1; then say "Claude Code already has the TypeFuse tools." claude_tools=yes return 0 fi if [ -n "${TYPEFUSE_TOKEN:-}" ]; then claude mcp add --transport http --scope user typefuse "$MCP" --header "Authorization: Bearer $TYPEFUSE_TOKEN" else claude mcp add --transport http --scope user typefuse "$MCP" fi say "Added the TypeFuse tools to Claude Code." claude_tools=yes } add_codex_tools() { if ! command -v codex >/dev/null 2>&1; then say "Codex: the codex command isn't on your PATH, so the TypeFuse tools weren't added." codex_tools=missing return 0 fi if codex mcp get typefuse >/dev/null 2>&1; then say "Codex already has the TypeFuse tools." codex_tools=yes return 0 fi if [ -n "${TYPEFUSE_TOKEN:-}" ]; then codex mcp add typefuse --url "$MCP" --bearer-token-env-var TYPEFUSE_TOKEN else codex mcp add typefuse --url "$MCP" fi say "Added the TypeFuse tools to Codex." codex_tools=yes } # An agent whose command wasn't found gets its tools by running this again once it is installed. missing_steps() { if [ "$claude_tools" = missing ]; then say " Claude Code: install it (or put the claude command on your PATH), then run this installer again to add the TypeFuse tools." fi if [ "$codex_tools" = missing ]; then say " Codex: install it (or put the codex command on your PATH), then run this installer again to add the TypeFuse tools." fi } # The first prompt, once an agent has (or is about to have) the tools. ask_steps() { if [ "$claude_tools" = yes ] || [ "$claude_tools" = pending ] || [ "$codex_tools" = yes ]; then say " Then ask your agent: Use TypeFuse to build a Decision that judges ." fi } if [ "$do_claude" = yes ]; then install_skill "$HOME/.claude" --claude add_claude_tools fi if [ "$do_codex" = yes ]; then install_skill "$HOME/.codex" --codex add_codex_tools fi say "" say "Next:" missing_steps if [ -n "${TYPEFUSE_TOKEN:-}" ]; then if [ "$claude_tools" = yes ]; then say " Claude Code: the TypeFuse tools use your access token (TYPEFUSE_TOKEN); no sign-in needed." fi if [ "$codex_tools" = yes ]; then say " Codex: the TypeFuse tools read your access token from TYPEFUSE_TOKEN; no sign-in needed." fi elif [ "$claude_tools" = yes ] || [ "$codex_tools" = yes ]; then if [ "$claude_tools" = yes ]; then say " Claude Code: run /mcp, choose typefuse and then Authenticate." fi if [ "$codex_tools" = yes ]; then say " Codex: run codex mcp login typefuse and confirm in your browser." fi say " For CI or an agent that runs without you, use an access token instead: $APP/agents#ci" fi ask_steps