CtrlK
BlogDocsLog inGet started
Tessl Logo

jbaruch/coding-policy

General-purpose coding policy for Baruch's AI agents

Quality

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

tessl-hygiene.shskills/onboard-repo/

#!/usr/bin/env bash
# Apply tessl-artifact hygiene to a consumer repo being onboarded:
#   1. Pin every jbaruch/*-owned dependency in tessl.json to "latest" (stops the
#      auto-update churn that rewrites a pinned version on each coding-policy
#      release). Third-party pins (tessl-labs/*, tessl/npm-*, etc.) are left as-is.
#   2. Ensure .gitignore carries the tessl-generated artifacts block so agents
#      never commit per-developer / per-agent output. AGENTS.md / CLAUDE.md /
#      GEMINI.md are intentionally NOT ignored — tessl appends to them and they
#      don't churn, so they stay committed.
#
# Idempotent: a jbaruch/* dep already at "latest" is left untouched; the block is
# added only when its marker is absent.
#
# Usage: tessl-hygiene.sh
# Out:   one JSON object on stdout:
#          {"tessl_json":"pinned-latest|unchanged|absent",
#           "gitignore":"created|appended|unchanged"}
# Exit:  0 on success; non-zero with a stderr diagnostic on failure.
set -euo pipefail

MARKER="=== Tessl-generated artifacts (managed by jbaruch/coding-policy) ==="

gitignore_block() {
  cat <<'EOF'
# === Tessl-generated artifacts (managed by jbaruch/coding-policy) ===
# Regenerated by `tessl install` (analogous to node_modules). Only tessl.json
# (the manifest) is committed; everything below is per-developer / per-agent
# output. AGENTS.md / CLAUDE.md / GEMINI.md are NOT ignored — tessl appends to
# them and they don't churn. Shared dirs (.github, .vscode) keep everything else;
# only tessl's own paths are listed.
.tessl/
.agents/
.mcp.json
.claude/settings.json
.claude/skills/tessl__*
.codex/config.toml
.codex/skills/tessl__*
.gemini/settings.json
.cursor/mcp.json
.cursor/hooks.json
.cursor/rules/tessl__*
.cursor/skills/tessl__*
.openhands/hooks.json
.openhands/skills/tessl-*
.github/mcp.json
.github/hooks/tessl.json
.github/skills/tessl__*
.vscode/mcp.json
.vscode/skills/tessl__*
# === end Tessl-generated artifacts ===
EOF
}

main() {
  command -v jq >/dev/null 2>&1 \
    || { echo "error: jq is not installed; install with 'brew install jq' (macOS) or 'apt install jq' (Debian/Ubuntu) and re-run" >&2; exit 2; }

  local repo_root
  repo_root=$(git rev-parse --show-toplevel 2>/dev/null) \
    || { echo "error: not inside a git worktree — run from within the consumer repo" >&2; exit 1; }
  cd "$repo_root"

  # 1. Pin jbaruch/* deps in tessl.json to latest.
  local tj_state="absent"
  if [[ -f tessl.json ]]; then
    local pinned
    pinned=$(jq -r '[.dependencies // {} | to_entries[] | select((.key | startswith("jbaruch/")) and .value.version != "latest")] | length' tessl.json) \
      || { echo "error: tessl.json is not valid JSON — fix it and re-run" >&2; exit 1; }
    if [[ "$pinned" == "0" ]]; then
      tj_state="unchanged"
    else
      local tmp; tmp=$(mktemp) || { echo "error: mktemp failed while updating tessl.json" >&2; exit 1; }
      if ! jq --indent 2 '.dependencies |= with_entries(if (.key | startswith("jbaruch/")) then .value.version = "latest" else . end)' tessl.json > "$tmp"; then
        rm -f "$tmp" || echo "warning: could not remove temp file ${tmp} — remove it by hand" >&2
        echo "error: failed to rewrite tessl.json" >&2
        exit 1
      fi
      mv "$tmp" tessl.json
      tj_state="pinned-latest"
    fi
  fi

  # 2. Ensure the gitignore block is present. grep exit is classified explicitly
  # (0 present / 1 absent / >1 read error) per rules/error-handling.md — never
  # collapsed to "absent".
  local gi_state
  if [[ -f .gitignore ]]; then
    local grc=0
    grep -qF "$MARKER" .gitignore || grc=$?
    if (( grc == 0 )); then
      gi_state="unchanged"
    elif (( grc == 1 )); then
      # Absent: append. Separate from prior content with a blank line when the
      # file lacks a trailing newline; a tail failure is a real read error.
      local last
      last=$(tail -c1 .gitignore) || { echo "error: cannot read .gitignore — check its permissions and re-run" >&2; exit 1; }
      [[ -n "$last" ]] && echo >> .gitignore
      gitignore_block >> .gitignore
      gi_state="appended"
    else
      echo "error: reading .gitignore failed (grep exit ${grc}) — check it is a readable text file and re-run" >&2
      exit 1
    fi
  else
    gitignore_block > .gitignore
    gi_state="created"
  fi

  jq -n --arg t "$tj_state" --arg g "$gi_state" '{tessl_json: $t, gitignore: $g}'
}

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
  main "$@"
fi

README.md

tile.json