Config
Skill SashaMarchuk/claude-plugins/plugins/claude-migrate/skills/config
Sasha Marchuk's Claude Code plugins — opinionated tooling for ticket management, automation, and everyday engineering workflows. Marketplace install: /plugin marketplace add SashaMarchuk/claude-plugins
npx -y skills add SashaMarchuk/claude-plugins --skill configAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 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.
What its author says it does
Copied from the file, not written here
(beta) Edit a migration run's settings between steps - profile tier, worker/seed parallelism, cost and brief thresholds, naming scheme, and the bucket role display labels - and re-author or swap the source/sink connector via a short interview. Writes the authoritative fields through bin/state.sh and mirrors record-only fields into config.yaml. Use when the user types /claude-migrate:config, or says "change the tier", "set parallelism", "raise the cost limit", "rename the buckets", "swap the connector", "use the live source instead of the export".
SKILL.md
10.6 KB, as published. Nobody here has run it
Role
Interactively edit one run's configuration. Two surfaces: (1) run-level settings that state.json is authoritative for (profile.*, parallelism, thresholds, naming) - written through bin/state.sh and mirrored into config.yaml as a human record; (2) the bucket role display labels and other record-only knobs that live in config.yaml; (3) the active SOURCE/SINK connector contract (source-connector.md / sink-connector.md), which you can swap to a shipped template or re-author via interview. This skill applies changes FORWARD only and refuses edits that would corrupt work already committed (a synthesize/apply already in flight).
Invocation
/claude-migrate:config [<run-name>] [<area>]
<run-name>optional. If omitted, auto-detect: list.planning/claude-migrate/and if exactly one run dir exists, use it; otherwise print available runs and exit.<area>optional shortcut: one oftier | parallelism | thresholds | naming | buckets | source | sink. If omitted, present the full menu (Step 2).
Protocol
Step 1: Locate the run + snapshot current config
- Parse
<run-name>and the optional<area>from$ARGUMENTS. - If
<run-name>absent:ls .planning/claude-migrate/- if exactly one dir, use it; else print available runs and exit. RUN_PATH=".planning/claude-migrate/<run-name>".- If
$RUN_PATH/state.jsonis missing, STOP: "No such run. Initialize with/claude-migrate:init <run-name>first." - Read the current values to show the user what they are changing FROM:
CUR_STEP=$(bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh get "$RUN_PATH" .current_step)
jq '{profile, decisions:{naming_convention:.decisions.naming_convention}, input:.input.mode, output:.output.mode}' "$RUN_PATH/state.json"
sed -n '1,200p' "$RUN_PATH/config.yaml"
Step 2: Pick an area (AskUserQuestion, unless <area> was given)
Use AskUserQuestion with header "Which setting do you want to change?" and options:
- Profile tier (model choice + /ultra gate rigor + suggested parallelism)
- Parallelism (worker fan-out; seed pacing)
- Thresholds (cost guardrails + max brief size + copy-page inline limits)
- Naming (how migrated chats are titled)
- Bucket labels (display names for the four roles)
- Source connector (swap or re-author the export/live contract)
- Sink connector (swap or re-author the copy-page/browser contract)
Step 3: Forward-only safety check (refuse unsafe edits)
Before writing, gate on CUR_STEP:
- Tier / models: if
CUR_STEP == "synthesize"or later (build-page,verify-gate,ready,pre-apply-gate,apply,finalize,done), REFUSE a tier change: "synth_model and the gate rigor are already committed for this run; a new tier applies forward only and there is no forward work left to apply it to. Start a new run if you need a different tier." - Parallelism: safe to change any time the relevant queue has NOT fully drained; it only affects future
launch-worker.shterminals. Already-running workers keep the model and count they started with - say so. - Thresholds: cost guardrails are read at the G-COST gate; refuse to lower
hard_stop_usdretroactively ifdecisions.cost_acknowledged == trueandCUR_STEPis pastfilter-gate(the cost was already approved).max_brief_tokens/ inline limits are safe to change beforedistill/build-pagerespectively; warn if changed after, because existing briefs/pages will not be regenerated unless re-run. - Naming: safe before
distill; afterdistillthe briefs already hold derived titles, so warn that a change only affects re-distilled units. - Bucket labels: always safe (display-only).
- Connector swap: REFUSE if
CUR_STEPis pastsplit(units are already extracted under the current source contract; changing the source mid-run would desync the corpus). For sink: refuse a swap onceapplyhas started. Beforesplit, a swap is free. If a change is refused, explain why and stop - do NOT partially apply.
Step 4: Apply the change
Tier
Validate against the closed enum {small, medium, large, xl}; reject others with the valid list. Set the whole profile sub-object so downstream skills read it without re-deriving. Per-tier values:
| tier | preflight_model | distill_model | synth_model | validator_model | ultra_gate_tier | parallelism | seed_parallelism |
|---|---|---|---|---|---|---|---|
| small | haiku | haiku | sonnet | sonnet | --small | 1-2 | 1 |
| medium | haiku | sonnet | sonnet | opus | --medium | 2-3 | 1 |
| large (default) | haiku | sonnet | opus | opus | --large | 4 | 1 |
| xl | haiku | opus | opus | sonnet | --xl | 5-10 | 1 |
Cross-model rule (runtime-enforced by verify): validator_model != distill_model. The table satisfies it; if you ever edit the table re-verify it. seed_parallelism stays 1 in v0.1.0 regardless of tier (in-session serial apply). Write:
bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh set "$RUN_PATH" .profile '<full-profile-json-object>'
Parallelism
profile.parallelism(integer >= 1): worker terminals for preflight/distill.profile.seed_delay_ms(integer >= 0): pacing between seed submissions in browser apply.profile.seed_parallelism: MUST remain 1 in v0.1.0. If the user asks for more, refuse and explain it is reserved for the future CDP-library path.
bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh set "$RUN_PATH" .profile.parallelism <N>
bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh set "$RUN_PATH" .profile.seed_delay_ms <MS>
Thresholds
State.json profile fields: max_brief_tokens, inline_card_limit, inline_byte_limit, ok_wait_ms, breaker_threshold, capture_screenshots. Cost guardrails (warn_usd, hard_stop_usd, warn_chat_count, warn_chat_tokens) live in config.yaml under cost: and are read at the G-COST gate. If the user turns capture_screenshots ON, WARN: per-attempt screenshots may capture PII; they are excluded from git by the run-dir .gitignore, and a banner warning fires in apply.
bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh set "$RUN_PATH" .profile.max_brief_tokens <N>
Then mirror the cost block into config.yaml (Step 5).
Naming
decisions.naming_convention:keep(default; derive a title only when the original name is empty/generic) orcustom:<scheme>. For custom, drive a structured pick with a prefilled worked example (Name DD.MM tag) via AskUserQuestion, then store the resolved scheme string.
bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh set "$RUN_PATH" .decisions.naming_convention '<keep|custom:SCHEME>'
Bucket labels (display-only)
The four ROLES are a closed enum (GROUPED | STANDALONE | REFERENCE | DROP); you may relabel how each is shown but NEVER add or remove a role. Edit the bucket_labels: map in config.yaml only (the core switches on the role enum, never on the label). Read the current labels, ask for new strings, and write config.yaml.
Source / Sink connector (swap or re-author)
A connector is a markdown CONTRACT (not code) copied into the run dir. Two paths via AskUserQuestion ("Swap to a shipped template, or re-author the current one?"):
- SWAP to a shipped template - copy it over the run's connector (overwrites the user-editable copy in the run dir, never the shipped template):
If the swap changes# SOURCE options: export-file (default) | browser (live) cp ${CLAUDE_PLUGIN_ROOT}/templates/sources/export-file.md "$RUN_PATH/source-connector.md" # SINK options: copy-page (the reliable floor) | browser (accelerator) cp ${CLAUDE_PLUGIN_ROOT}/templates/sinks/browser.md "$RUN_PATH/sink-connector.md"input.mode(export <-> live) oroutput.mode(copy-page <-> auto), update the matchingstate.jsonfield too:bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh set "$RUN_PATH" .input.mode '<export|live>' bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh set "$RUN_PATH" .output.mode '<copy-page|auto>' - RE-AUTHOR via interview - a connector.md MUST implement all 7 ops for its side. Interview the user for each section and Write the file. Required SOURCE sections (§5.1):
enumerate,extract_unit,extract_projects,unit_project_ref,account_check,citation_anchor,forbidden_fields. Required SINK sections (§5.2):prepare,dedupe_probe,create_project,seed_unit,finalize_unit,finalize_run,rate_limit_check. Open the file with the copy-first banner and, for browser/live sources, the mandatory secret-strip note. Never hardcode a secret in a connector - reference an env var. After re-authoring, advise re-running/claude-migrate:runso /ultra Gate 1 re-validates the new contract.
Step 5: Mirror record-only fields + confirm
For any state.json field that also appears in config.yaml (tier, parallelism, thresholds, naming, cost block, bucket_labels), update the config.yaml copy so the human record stays consistent (state.json remains authoritative for the fields it tracks). Then print a confirmation:
Config updated for run <run>:
<field>: <old> -> <new>
...
Effect: applies on the NEXT step. Already-running workers keep their started settings.
Next action: /claude-migrate:run <run> (or /claude-migrate:progress <run> to review)
Hard rules
- Forward-only. NEVER alter completed work or apply a tier/model change once
synthesizehas committed it. Refuse with a clear reason rather than corrupting state. - All
state.jsonmutations go throughbin/state.sh(locked, atomic, injection-defended). NEVER hand-editstate.json. config.yamlis a human record for the fieldsstate.jsonalso tracks; on conflictstate.jsonwins. Keep them consistent after every change.- The four bucket ROLES are a closed enum. You may relabel them in
config.yaml; you may NEVER add or remove a role. seed_parallelismstays 1 in v0.1.0. Refuse any higher value.- A re-authored connector MUST implement all 7 ops for its side and MUST NOT hardcode a secret (reference env vars). Browser/live sources MUST keep the mandatory secret-strip note.
- Never reference any specific domain in defaults, examples, or labels; use neutral placeholders (
Project Alpha,topic-1).
Gives 0 of the 12 instructions most project setup skills give
Counted across 999 of the 1,637 authors here whose files we hold, read 2026-08-06
- ask one question at a timein 29 of 999, across 28 files
- detect the package manager from lockfilesin 28 of 999, across 9 files
- present findings to the userin 25 of 999, across 4 files
- explore current repo statein 24 of 999, across 3 files
- update the agent skills block in place if it existsin 24 of 999, across 3 files
- install husky lint-staged and prettierin 23 of 999, across 4 files
- create the lintstagedrc filein 22 of 999, across 3 files
- commit all changed filesin 22 of 999, across 3 files
- run lint-staged to verify it worksin 22 of 999, across 3 files
- initialize huskyin 21 of 999, across 2 files
- create the husky pre-commit filein 21 of 999, across 2 files
- create a prettierrc file if missingin 21 of 999, across 2 files
Said here and by no other author read
- auto-detect a run or list available runs
- snapshot current configuration values before editing
- present the configuration area menu
- check the current step before applying edits
- refuse unsafe edits with a clear reason
- write state mutations through the state script
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once.