agentsclimarketplace

Setup

Skill bllshttng/footnote/skills/setup

Schema-driven setup wizard for footnote settings. Derives its question set from the Pydantic config model (the single source of truth) instead of a hardcoded list; asks only the real per-project decisions and defaults the rest.From its SKILL.md

Install
npx -y skills add bllshttng/footnote --skill setup

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

9.8 KB, as published. Nobody here has run it

Setup Wizard

Creates / updates config.toml by asking only the handful of decisions that genuinely vary per project, then writing each answer through the validated fno config set path. Everything else is defaulted by the model.

Single source of truth. This skill does NOT hardcode a question list. It asks fno for the questions, so the wizard can never drift from the schema and can never write a key that does not exist:

fno config setup plan              # the ~4-6 "always" decisions, as JSON
fno config setup plan --advanced   # also the "advanced" tier

Each emitted field carries {path, type, default, tier, question, default_source, doc}.

Modes

CommandScopeFields asked
/setupglobal (~/.fno/config.toml)the always tier (the real decisions)
/setup advancedglobalalways + advanced (progressive disclosure)
/setup localproject (.fno/config.toml)same questions, written project-scoped

There is no separate "full" mode and no hand-maintained question table: advanced is just "ask the advanced tier too". Keys whose tier is never are always defaulted and never surfaced.

Step 0: Check existing settings

GLOBAL_PATH="$HOME/.fno/config.toml"; LOCAL_PATH=".fno/config.toml"
[[ -f "$GLOBAL_PATH" ]] && echo "global exists" || echo "no global"
[[ -f "$LOCAL_PATH" ]]  && echo "local exists"  || echo "no local"

If the target file already exists, AskUserQuestion: "Found existing settings. Update in place, or start fresh?" Updating is non-destructive: fno config set preserves every key it does not touch (and any unknown/extra keys), so you only overwrite the answers the user changes.

Step 1: Get the question plan

fno config setup plan              # /setup and /setup local
fno config setup plan --advanced   # /setup advanced

Parse the JSON. For each field, ask the user using its question text. Use the default as the pre-filled answer and default_source as an inference hint:

  • repo-slug -> default from basename $(git rev-parse --show-toplevel).
  • readme -> infer a one-line vision from the README's first paragraph.
  • auto-detect-> detect from the repo (vault name, workspace topology).

Today the always set is small. It covers Obsidian on/off (plus vault name), project vision, backlog id_prefix, external reviewer(s), and auto-merge on/off. Ask only what fno config setup plan returns. Do not invent extra questions.

Step 2: Write each answer through fno config set

Write the GLOBAL scope by default; pass --local for /setup local:

fno config set <path> <value>            # global
fno config set <path> <value> --local    # project-scoped (/setup local)

fno config set coerces and schema-validates the value, then writes atomically under a lock. Type handling:

  • bool: true / false.
  • int: a bare number.
  • list (e.g. config.review.external_reviewers): a comma-separated string (gemini,codex) or a JSON array (["gemini","codex"]). An empty value is an empty list (external review disabled).
  • string: as typed.

A rejected value (e.g. a reserved id_prefix like tgt-, or a length/charset violation) exits non-zero and leaves the file unchanged. Re-prompt and retry; NEVER hand-write the file to bypass validation.

Example writes:

fno config set config.obsidian.enabled true
fno config set config.obsidian.vault myvault
fno config set config.project.vision "A footnote-style delivery pipeline."
fno config set config.backlog.id_prefix myproj      # normalized; reserved families rejected
fno config set config.review.external_reviewers gemini,codex
fno config set config.auto_merge.enabled false

Step 2b: Review gate (how a PR is allowed to go green)

fno config setup plan asks about config.review.external_reviewers (which logins to request and recognize). The GATE - what fno-agents loop-check REQUIRES before /target promises - lives in three advanced-tier keys the default plan does not surface. Most users never learn the bot-less options exist. Offer the choice explicitly. Default = none / PR + CI only. These are additive - a repo can require both a bot AND a local sigma pass:

"How does review gate a PR before /target considers it done?

  1. GitHub App bots - a bot login (e.g. chatgpt-codex-connector, gemini-code-assist) must post a review. Needs the bot installed on the repo.
  2. Local attestation - /target runs a /review sigma panel in-session and attests on a clean pass; no GitHub bot needed. Best for a solo / claude-only harness. (declare is a bare 'I looked' self-cert, not a review - offer it only as an escape hatch.)
  3. CLI peers - a codex/gemini CLI posts a real PR review under a distinct machine account.
  4. None - PR + CI only (default)."

Map the answer to keys and write them (use --local for a per-repo gate; global otherwise). /target runs whatever you set here before it promises - so a reviewers/peers gate always has a producer and never hangs the loop:

# 1. GitHub bots (the gate list, distinct from external_reviewers)
fno config set config.review.github_apps chatgpt-codex-connector,gemini-code-assist --local
# 2. Local attestation (sigma = real six-agent review; declare = self-cert escape hatch)
fno config set config.review.reviewers sigma --local      # or: declare
# 3. CLI peers (also set the identity the review posts under + its PAT env var)
fno config set config.review.peers codex --local
fno config set config.review.peer_identity fno-peer-bot --local
fno config set config.review.peer_token_env GH_PEER_TOKEN --local

Leaving all three empty keeps today's PR + CI-only behavior.

Step 3: Workspace / project topology (config.work.workspaces)

The config.work map (workspace -> projects[]) is topology, not a scalar leaf, so it is not asked via fno config setup plan. When setting up a workspace, auto-detect the current project and confirm it:

NAME=$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")
# detect type/stack/package_manager from package.json / pyproject.toml / Cargo.toml / go.mod

Show a one-shot summary (name, path, type, stack, package manager) and confirm. Offer to add related projects in the same workspace (loop, auto-detecting each). This block is written as a single config.work.workspaces.<slug> map; if fno config set cannot express the nested list in one call, write the config.work block directly to the target settings file (it is the one structural exception), then re-run fno config doctor to confirm it validates. The name field under each project is the cross-project routing identity (what fno agents mail --to-project <name> uses); it is distinct from config.project.id.

Step 4: Post-merge parking-lot (per repo)

The post-merge ritual needs a repo-relative parking-lot path that is NOT derived from the project name (the vault area often differs). Delegate to the dedicated scaffold rather than guessing:

fno config setup post-merge

Step 4b: Offer global shell integration (OPTIONAL, consent-gated)

The mux (fno mux) auto-injects OSC 133 command-block markers into the shells IT spawns (config.mux.shell_integration: mux-panes, on by default), so blocks "just work" in mux panes with zero config and WITHOUT touching the user's rc.

Blocks in the user's OTHER terminals (iTerm, Terminal.app, a non-mux tab) need the markers too. Offer to add ONE eval line to their shell rc - never silently, always reversible:

# Detect their shell, then OFFER (ask [y/N], default no):
#   "Add OSC 133 block markers to your global <zsh|bash> rc so blocks work in
#    every terminal, not just mux panes? This appends one commented line to
#    ~/.zshrc (or ~/.bashrc). [y/N]"
# On y ONLY, append (idempotent - skip if _FNO_OSC133 already present):
grep -q _FNO_OSC133 ~/.zshrc 2>/dev/null || {
  printf '\n# fno OSC 133 block markers (remove this line + the next to undo)\n' >> ~/.zshrc
  echo 'eval "$(fno mux shell-init zsh)"' >> ~/.zshrc
}

Never edit the global rc without an explicit yes. off in config.mux.shell_integration disables the mux-pane injection too; the manual fno mux shell-init eval always works.

Show the resulting config and validate:

fno config doctor
fno config get config.review.external_reviewers
fno doctor --blockers

fno config doctor checks your paths. fno doctor --blockers checks this machine: stale install, dead LaunchAgents, low open-file limit, and the other findings that make the fleet misbehave. Relay its lines to the user verbatim. Do not summarize them away. A blocker is exactly the thing a new user needs to see and act on.

For the full, generated reference of every key (type, default, doc), point the user at docs/configuration-guide.md (regenerated by fno config schema --markdown).

What this wizard does NOT write

The following legacy keys are gone: external_reviewer (singular - use the external_reviewers list), budget_cap, commit_style, profile, default_size, docs.*, schema_sources.*, linear.*, expertise, plans.full_path. They are not in the schema, so the wizard cannot write them. A CI guard (cli/tests/test_config_schema_drift.py) fails the build if the wizard ever surfaces a key that is not a real model leaf.

Companions (RTK)

If RTK is detected (e.g. ~/code/dotfiles/bin/rtk-claude-hook.sh), note that it is already wired and do NOT run rtk init -g (it would double-wire). This is informational only; it is not a config.toml key.

Known Limitations and Deferred Work

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.