Skip to main content

setup-wizard

Conversational onboarding for the supported full agentic research-brain path. Offers a starter pack or interview, establishes sources through intake/source-manage, writes the topics+sources config (config/topics.yaml + config/sources.yaml — YAML only; an unmigrated legacy .md install is stopped and offered migrate-config), config/channels.yaml, config/schedule.yaml and derived config/tags.yaml, then closes with scripts/setup_check.py activation status. Advanced users can choose RSS Digest Lite, SMTP, or Telegram Bot API. Triggers: «set up sources», «configure», «let's set up», «first-time setup», «настроить источники», «онбординг», «starter pack».

Source facts

Repository
artemrudenko/research-brain-public
Last source activity
October 11, 2026 at 14:32
Detected SKILL.md language
English
Stars
0
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
setup-wizard
description
Conversational onboarding for the supported full agentic research-brain path. Offers a starter pack or interview, establishes sources through intake/source-manage, writes the topics+sources config (config/topics.yaml + config/sources.yaml — YAML only; an unmigrated legacy .md install is stopped and offered migrate-config), config/channels.yaml, config/schedule.yaml and derived config/tags.yaml, then closes with scripts/setup_check.py activation status. Advanced users can choose RSS Digest Lite, SMTP, or Telegram Bot API. Triggers: «set up sources», «configure», «let's set up», «first-time setup», «настроить источники», «онбординг», «starter pack».
metainfo
{"type":"worker","domain":"config","last_updated":"2026-07-06T00:00:00.000Z","successor":["source-manage"]}
# setup-wizard — guided config onboarding Turns a freshly-unpacked research-brain into a configured and truthfully activated one. The user opens the project root in Cowork / Claude Code, says "let's set up sources", and this skill leads with the supported product default: > We'll set up the full research-brain path. Advanced users can choose RSS Digest Lite or headless transports. The normal path does not ask the user to choose an implementation mode. It talks in user outcomes: sources, delivery, schedule, first value, and the next action. Advanced setup is explicit and preserves RSS Digest Lite, SMTP, and Telegram Bot API for users who need a headless/no-agent path. It is **conversational** and **idempotent**: on first run it fills in the shipped templates (or copies the starter); on a later run ("let's reconfigure email", "add a topic", "change the timezone") it re-reads the current config and changes only what the user asks. "Add a topic" also updates `tags.yaml`; "change the timezone" only touches `schedule.yaml`. The config files this skill owns: | File | Format | Written in step | |------|--------|-----------------| | `config/topics.yaml` | YAML (schema CONVENTIONS §2.3) — the topics config | a — Topics | | `config/tags.yaml` | YAML (fixed registry, CONVENTIONS §11) | a — derived from topics | | `config/sources.yaml` | YAML (schema §2.3, incl. per-source `tier`) — the sources config | b — Sources | | `config/channels.yaml` | YAML (fixed schema, CONVENTIONS §2.1) | c — Delivery | | `config/schedule.yaml` | YAML (fixed schema, CONVENTIONS §2.2) | d — Schedule | **Config format rule (§2.3):** `config/sources.yaml` / `config/topics.yaml` are the ONLY sources/topics config the runtime reads — every ordinary path in this skill reads/writes the YAML twins via the `manage_sources.py` backend. The legacy `.md` tables are retired (0.8.0): when Step 0 detects an unmigrated legacy install (real `.md` config, no YAML twin), the wizard STOPS and offers exactly one action — `python3 scripts/schema.py migrate-config` — then continues on the YAML files. The shipped archive carries the twins as empty structures; the backend fills them. Secrets are **never** written by this skill — they go in `config/.env` (copied from `config/.env.example`); the YAML only ever holds the *name* of the env var. --- ## When to Use **Use when:** - The user says: "set up sources", "configure", "let's set up", "first-time setup", "onboarding", "starter pack", "настроить источники", "онбординг", "давай настроим". - A fresh checkout where `config/` files still hold the shipped EXAMPLE placeholders. - The user wants to change one part of an existing config ("reconfigure Telegram", "add a topic", "change the digest day", "change the timezone") — run only the relevant step. Adding/removing a topic re-derives `tags.yaml` too. **Skip / don't use for:** - Filling in secret values (tokens, passwords, webhook URLs). Direct the user to `config/.env`. - Running a collection or building a digest — collection is a scheduled task (`schedule/collect-*.md`, not a skill); building is the `digest-build` skill (sending is `digest-deliver`). setup-wizard only writes config (Step f *offers* a rehearsal but sends nothing). - Editing `brain/`, `pipeline/`, or any file outside `config/`. - Hand-gardening `tags.yaml` long-term — after the first derivation it grows automatically via the weekly brain-hygiene pass (`scripts/validate_brain.py`). --- ## DO / DON'T **DO:** - Inspect repo state first; tell the user whether this is a first run or a reconfigure. - On first run, OFFER the starter-pack fast path before the full interview (Step 0). - Ask one topic at a time. Confirm the collected values back before writing each file. - Derive `config/tags.yaml` from the topics (nested `domain/topic`), show it, confirm. - Ask a per-source `Tier` (high/medium/low credibility), default `medium`. - For each chosen channel, explain its PREREQUISITES (MCP connected / webhook created / secret in `.env`). - Write `channels.yaml`, `schedule.yaml`, `tags.yaml` to their EXACT fixed schemas (CONVENTIONS §2.1 / §2.2 / §11). - Write the FULL schedule schema — `collect` / `curate` / `synthesis` / `digest` + `timezone`. - Use relative paths only (`config/...`, `pipeline/1-incoming/...`). Never absolute paths. - Keep topic names in sync between `topics.yaml`, `sources.yaml`, and the `tags.yaml` synonyms. - Detect source type from the URL (rss / blog / medium-tag / webpage); prefer `rss` when a feed exists. - After writing, run `python3 scripts/setup_check.py --runtime agentic --scheduler-state ready-not-registered` and report its activation checklist (Step f). - Before claiming `complete`, verify recurring execution is actually registered. A written `config/schedule.yaml` is only `ready, schedule not registered`. **DON'T:** - Don't write secrets (tokens, passwords, webhook URLs) into any `.yaml` or `.md`. Ever. - Don't change the structure / keys of the YAML schemas — only the values. - Don't wipe a configured file on a reconfigure run — re-read and patch only what changed. - Don't invent topics or sources the user didn't give. Leave a section empty rather than guess. - Don't interrogate the user about tags — derive them, show the result, ask one yes/no confirm. - Don't write absolute paths or any brand/project-specific hardcoding. - Don't actually send a digest — Step f is a dry-run rehearsal only. --- ## Inputs | Input | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `MODE` | enum `first-run` / `reconfigure` | no | auto-detected | Decided by inspecting config state (see Step 0) | | `USE_STARTER` | bool | no | asked on first run | Copy the starter pack instead of the full interview (Step 0) | | `TARGET` | string | no | all steps | For reconfigure: which part to change ("email", "topics", "schedule", "timezone"...) | | User answers | interactive | yes | — | Collected through the step-by-step interview | Use AskUserQuestion-style prompts: ask one focused question, wait, confirm, then move on. --- ## Steps ### Step 0 — Inspect repo state + offer the starter pack Determine where we are before asking anything. 1. Check which config files exist: `config/sources.yaml` + `config/topics.yaml` (the only sources/topics config the runtime reads), any leftover legacy `config/topics.md` + `config/sources.md`, plus `config/channels.yaml`, `config/schedule.yaml`, `config/tags.yaml`. Note any missing. 2. Detect whether the install is still a **shipped template** (not yet configured). Markers: - `sources.yaml` / `topics.yaml` exist (possibly as the shipped empty structures) → configured iff they carry real topics/sources (`python3 scripts/manage_sources.py list`). - **no YAML twin at all**, but `topics.md` / `sources.md` hold real topic/source content → an **unmigrated legacy install** (the state `scripts/sources/store.py` refuses loudly everywhere) — go to 2a. `.md` files carrying only `# EXAMPLE — replace` rows or the literal `Updated: YYYY-MM-DD` header are templates, not user data — they never block; treat the install as unconfigured. - `channels.yaml`: every channel has `enabled: false` AND `to: []` is empty AND `chat_id: ""` is empty → not yet configured. - `schedule.yaml`: present with default crons → treat as configurable (always offer). 2a. **Unmigrated legacy install → STOP; offer exactly one action — the migration** (never auto-apply): "Your sources/topics config is in the retired markdown format, which the runtime no longer reads — nothing (collection, validation, this wizard's writes) works until it is imported. Run `python3 scripts/schema.py migrate-config`? One command, nothing is lost — your `.md` files stay untouched as the rollback." On yes run it, show its output, and continue the wizard on the YAML files. On no, stop here — leave the config untouched and name the command for later; there is no `.md` path to continue on. 3. Decide `MODE`: - All config files are still templates → **first-run**. Greet, then go to the **starter-pack fork** below. - At least one file is configured → **reconfigure**. Ask which part the user wants to change (`TARGET`) and jump to only that step. Re-read the current file first. 4. Tell the user what you found: e.g. "Fresh setup — none of the config is filled in yet." or "Looks configured already — what would you like to change? (topics / sources / delivery / schedule / timezone / language)". On first run, lead with this exact default copy: > We'll set up the full research-brain path. Advanced users can choose RSS Digest Lite or headless transports. Do **not** ask the user to choose `agentic`, `headless`, or `RSS Digest Lite` unless they explicitly ask for advanced setup. ### Advanced setup fork Use this fork only when the user explicitly asks for advanced/headless setup, RSS Digest Lite, SMTP, Telegram Bot API, cron-only operation, or when the current runtime cannot support the recommended MCP transport. Advanced choices preserve existing capability: - **RSS Digest Lite** — deterministic RSS collection + sanitize + digest + headless delivery. This path requires at least one active `rss` source. - **Email SMTP** — set `provider: smtp`, collect SMTP host/user/recipient, and keep `password_env: SMTP_PASSWORD`. - **Telegram Bot API** — set `transport: bot-api`, collect `chat_id`, and keep `token_env: TELEGRAM_BOT_TOKEN`. The normal first-run path stays full agentic with MCP-first delivery defaults. **Starter-pack fork (first-run only).** Before the full interview, ask one question: > "Want a ready-to-go starter so you get a working setup in one step, then tweak? > It imports `config/sources.example-starter.md` + `config/topics.example-starter.md` > (public feeds for **tech-news** + **ai-ml**) into your `sources.yaml` / `topics.yaml`." - **Yes (`USE_STARTER`)** → copy the two starter files in as migration input: `cp config/sources.example-starter.md config/sources.md` and `cp config/topics.example-starter.md config/topics.md`. Stamp today's date over the `Updated: YYYY-MM-DD` header in both, then land them in the YAML config: `python3 scripts/schema.py migrate-config --force` (writes `config/sources.yaml` + `config/topics.yaml` from the copied starters; the copied `.md` files are import material only — they can be deleted after). Then **still derive `config/tags.yaml`** from the starter topics (Step a.4), and continue to delivery (Step c), schedule (Step d), language (Step e), and verify (Step f). Skip the topic/source interview (a.1–a.3, b). - **No** → run the full interview a → e, then f. Read commands (illustrative, relative paths): - `ls config/sources.yaml config/topics.yaml` — do the YAML twins exist yet? - `python3 scripts/manage_sources.py list` — what is actually configured (reads the YAML; on an unmigrated legacy install it fails with the migrate-config pointer — Step 2a). - `grep -l "EXAMPLE — replace" config/*.md` — leftover `.md` files that are templates, not user data (they never block; real `.md` content without YAML twins is Step 2a). - Read `config/channels.yaml` and check the `enabled:` flags. ### Step a — Topics / categories → `config/topics.yaml` (+ derive `config/tags.yaml`) 1. Ask: "What topics do you want to track? Give me a short name for each (e.g. `ai-agents`, `ai-governance`)." Collect a list. 2. For each topic, ask (can batch sensibly): include rules (what belongs), exclude rules (what to drop), and frontmatter tags (default to `[<name>]` if the user has no preference). 3. Confirm the full topic list back to the user. 4. **Derive `config/tags.yaml`** from the topics (auto-derive + grow — CONVENTIONS §11). For each topic, split a `<domain>-<topic>` name into a nested `domain/topic` tag: - `ai-agents` → domain `ai`, topic `agents` → tag `ai/agents` - `ai-governance` → domain `ai`, topic `governance` → tag `ai/governance` - `tech-news` → domain `tech`, topic `news` → tag `tech/news` - a single-word topic (`security`) → use it as the topic under a sensible domain, or `misc/<topic>` if no domain is implied; ask only if genuinely ambiguous. Then write the registry: - `domains:` — each domain mapped to its list of topics (e.g. `ai: [agents, governance]`). - `synonyms:` — map the **raw topic name** and obvious aliases to the canonical nested tag (`ai-agents: ai/agents`, `agentic: ai/agents`, `tech-news: tech/news`). This is what RSS `<category>` values and concept tags normalize through. - `pending: []` — empty quarantine for tags the system proposes later. Show the user the resulting tag list (e.g. "domains: ai → agents, governance; tech → news") and confirm with ONE yes/no — don't interrogate. Tell them: **"You never hand-manage tags — this vocabulary grows automatically. When a new tag recurs across ≥3 notes the weekly hygiene pass *recommends* it (`scripts/validate_brain.py`, advisory) and `scripts/promote_tags.py` *applies* the promotion from `pending:` into the registry."** Keep the file's header comment block intact; only fill `domains:` / `synonyms:` / `pending:`. 5. Write the topics into `config/topics.yaml`. First create each topic through the deterministic backend (it writes the YAML twins and keeps names in sync): `python3 scripts/manage_sources.py add-topic <name>` — then set the interview's include/exclude rules and tags on each entry by editing `config/topics.yaml` — one `topics:` entry per topic (schema CONVENTIONS §2.3); replace the backend's default prose with the user's answers: ```yaml topics: - name: ai-agents tags: [ai-agents, agents] include: "Substantive pieces about autonomous agents, orchestration, tool use." exclude: "Generic LLM hype with no agent angle; route product news elsewhere." ``` > On a **reconfigure** "add/remove a topic": use `manage_sources.py add-topic` / > `remove-topic` (it patches BOTH `config/topics.yaml` and `config/sources.yaml`), > AND re-derive the `tags.yaml` entry for that topic (add the `domain/topic` to > `domains:` + a `synonyms:` alias; never delete a tag that existing concepts may use — > leave it or fold it up to its domain). ### Step b — Sources per topic → `config/sources.yaml` (Skipped when the starter pack was copied — the starter already carries sources with tiers.) Source establishment should reuse the Phase 1 `intake` path when the user supplies OPML, a plain URL, or an explicit shortcut: - OPML import: run the `intake` flow, preview first, then apply only after confirmation. - Bare URL: run `python3 scripts/intake.py URL --json`; approve the proposed recurring-source handoff before persistence. - Explicit `/add <url>` or explicit monitor/add intent: route directly to `source-manage`. - Explicit `/save <url>` remains a read-it-later capture path and is not part of source setup unless the user deliberately wants to capture an article during onboarding. 1. For each topic from Step a, ask: "Which URLs should we collect `<topic>` from?" 2. For each URL, **detect the type** and confirm: - ends in `.xml` / `/feed` / `/rss` / `/atom`, or is a known feed path → `rss` - `medium.com/tag/<tag>` (optionally `/latest`) → `medium-tag` - a blog *index* page (e.g. `.../blog`) → `blog` - anything else (a single page, no feed) → `webpage` **Prefer `rss` whenever a feed exists** — say so to the user. The verified feed
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub