Skip to content
Back to skills

Setup

ASecurity

Interactive setup and onboarding. Use on first run, when changing stack/packs, or when healthcheck reports config issues.

  • 35 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 20, 2026
developmentjavascripttypescriptpythonrustgojavaphpshellbashreact

Works with

  • claude code
  • cli

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 20, 2026

npx -y skills add BULDEE/ai-craftsman-superpowers --skill setup --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Setup?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Setup
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/buldee-setup/badge)](https://www.skillsdirectory.com/skills/buldee-setup)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
model: sonnet
description: "Interactive setup and onboarding. Use on first run, when changing stack/packs, or when healthcheck reports config issues."
effort: medium
disable-model-invocation: true
---

# /craftsman:setup - Configuration Wizard


> The commands below call `craftsman-path`, which prints an absolute path
> inside this installation. The plugin's `bin/` is on PATH in the Claude Code
> Bash tool; on a host where it is not, call it by its full path
> (`<plugin root>/bin/craftsman-path`). Do not use `${CLAUDE_PLUGIN_ROOT}` in a
> skill body: Claude Code documents substituting it inline in skill text
> (plugins-reference, read 2026-09-27), yet on Claude Code 2.1.278 a skill that
> relied on it ran `source "/hooks/lib/config.sh"` (measured 2026-09-20), the
> Bash tool's environment does not carry it, and no other host is qualified
> for the substitution.

## Outcome Contract

- **Outcome**: a configuration derived from what the repository actually is, with only the undeterminable parts asked.
- **Done when**: the inferred conventions were shown before being written, .craft-config.yml is valid against the schema, and healthcheck reports no config error.
- **Evidence**: the conventions analysis output, the written config, and the healthcheck result.

## Modes

| Command | Description |
|---------|-------------|
| `/craftsman:setup` | Full interactive setup (default) |
| `/craftsman:setup --quick` | Zero-question auto-setup with smart defaults |
| `/craftsman:setup --refresh` | Regenerate observed artifacts (conventions skill, codemap) |
| `/craftsman:setup --global` | Workshop profile: asked once per machine, inherited by every project |

---

## Setup by Observation (ADR-0022)

Every mode (including `--quick`) ends with the observation step. The repository answers most setup questions itself; only ask the user what observation cannot determine (strictness preference, pack opt-ins).

1. Run the conventions analyzer and SHOW the user what was inferred before writing anything:
   ```bash
   bash "$(craftsman-path bin/craftsman-helper)" conventions analyze
   ```
2. On confirmation (automatic in `--quick` and `--refresh`), generate the project conventions skill:
   ```bash
   bash "$(craftsman-path bin/craftsman-helper)" conventions generate "$PWD/.claude/skills"   # Codex reads "$PWD/.agents/skills" instead
   ```
   This writes `.claude/skills/project-conventions/SKILL.md` (`.agents/skills/...` on Codex; `user-invocable: false`, loaded as background knowledge, shareable via git, freely editable).
3. Warm the codemap cache (review skills inject it as live context):
   ```bash
   bash "$(craftsman-path bin/craftsman-helper)" codemap >/dev/null
   ```

Regeneration is always explicit (`--refresh`), never silent: the generated file records its generation date and inputs.

---

## Workshop Profile (`--global`)

Asked once per machine, then never again. It records how this developer usually works, not what the current project is. The answers are written to `~/.claude/.craft-config.yml` and every project inherits them through the 3-level config (global, then project, then directory).

Two questions, no more:

1. **Which stack(s) do you usually work in?** Propose what is already installed on the machine, and map the answer to packs.
2. **Which quality tools do you like in each stack?** Propose the community standards from the tooling detector catalog:

   ```bash
   python3 "$(craftsman-path hooks/lib/tooling_detect.py)" "$PWD" --json
   ```

   The detector reports both what is declared here and what it suggests per stack (linters, architecture checkers, test runners, and the security section: secret scanners, dependency audit). For the workshop profile only the suggestion catalog matters, not this repository.

Record the answers under a `preferred_tools:` key:

```yaml
preferred_tools:
  php: ["PHPStan", "Deptrac", "PHPUnit"]
  javascript: ["ESLint", "Vitest"]
  security: ["Gitleaks"]
```

**Nothing is ever installed (ADR-0019).** A preference is a proposal that project init will offer later. Say this out loud when you write the profile so nobody expects a `composer require` or an `npm install` to have run.

---

## Situational Init (default project flow)

The default flow when `/craftsman:setup` runs inside a project. Observe first, then ask at most four short questions. Never ask what the repository has already answered.

### Step A: Observe

```bash
bash "$(craftsman-path bin/craftsman-helper)" conventions signals
```

It prints one JSON line:

```json
{"existing_project": true, "commit_count": 412, "has_tests": true, "has_ci": false, "legacy_signal": true}
```

Read it as: `existing_project` becomes true past 20 commits, `legacy_signal` is true when an existing project has no tests or no CI. These are prefills, not decisions. The user still confirms.

### Step B: Confirm (4 questions maximum)

One `AskUserQuestion` call, every answer prefilled from the signals. Wording matters: these questions are read by people who have never heard of a ratchet, a baseline, or a doctrine. No jargon, no rule codes, no acronyms. Ask exactly these four and nothing else:

| Question | Prefilled from | What it decides |
|---|---|---|
| Existing project or a new one? | `existing_project` | how the baseline is taken, AND the strictness ceiling |
| Prototype or heading to production? | `legacy_signal`, `has_tests` | strictness, within that ceiling |
| Solo or team? | `has_ci` | whether a CI template and a doctrine export are proposed |
| Maximum help or maximum autonomy? | nothing, ask plainly | `guided: true` or `guided: false` |

Offer plain answers, never internal vocabulary:

- Question 1: "It already exists" / "I am starting it right now"
- Question 2: "It is a prototype, I am exploring" / "It is going to production"
- Question 3: "I work alone on it" / "We are several on it"
- Question 4: "Explain every blocked change to me" / "Just block, stay short"

Mapping, applied silently:

| Answer | Effect |
|---|---|
| Already exists | photograph the current state as the baseline, and cap strictness at `moderate` |
| Starting right now | baseline starts empty, zero tolerance from the first file |
| Prototype | `strictness: moderate` |
| Going to production, on a NEW project | `strictness: strict` |
| Going to production, on an EXISTING one | `strictness: moderate` |
| Alone | no CI proposal |
| Several | propose `craftsman-ci init` (pipeline template) and `craftsman-ci export` (shareable doctrine) |
| Explain every blocked change | `guided: true` |
| Just block, stay short | `guided: false` |

**Question 1 outranks question 2, and this is the single most important line in
the mapping.** It is enforced by `config_default_strictness` in
`hooks/lib/config.sh`, not by this table: a decision that opens or closes the
front door of the gate cannot depend on a model following prose. A codebase with three years of history is in production, so the
truthful answer to question 2 is "going to production", and mapping that
straight to `strict` selects the setting that refuses most of the repository on
the first edit. Measured on a real Symfony application, 400 files sampled: 98%
have no `declare(strict_types=1)` and 88% are not `final`.

`moderate` relaxes design and style, never a boundary and never security:
`LAYER*` and `SEC*` keep their declared severity under it, which is asserted in
`tests/core/test-rules-engine.sh`. What it stops doing is refusing an edit
because of a class declaration two hundred lines above the change.

That sentence was written here before it was true. `SEC*` was missing from the
carve-out, so this change would have made a hardcoded secret advisory on every
repository with history, justified by a claim in a document a model reads to
decide. It is true now because the engine was fixed and a test holds it.

The baseline is the other half of the same answer: `craftsman-ci baseline`
records what the repository already carries, so a recorded violation reports
without blocking while a new one still refuses the write. Step D runs it.

The mark lives in `.craftsman-baseline.json` at the repository root, and the
question "which mark answers for this file" is settled by the file's own
directory, never by where the shell happens to be: a pipeline running from a
package directory, and a hook fired with whatever working directory the editor
has, read the same mark. A repository nested inside another (a submodule, a
package that took its own mark) answers for its own files.

Taking the mark is also what buys `strict` back. An existing repository whose
debt has never been measured defaults to `moderate`, where only a boundary or a
secret blocks; once the mark is taken, the default is `strict` again, because
the debt `strict` would refuse is now recorded and reported without blocking.

Naming a rule in this repository's `.craft-rules.yml` outranks the mark:
`PHP001: block` blocks a recorded violation too, which is how a project takes
one rule back out of the debt once it has been cleaned up. The same line in the
global `~/.claude/.craft-config.yml` does not, because a preference held across
every repository on the machine is not a statement about this one.

The mark is taken once. A second `craftsman-ci baseline` is refused, and a
deliberate re-mark needs `--re-baseline --reason "..."` and says out loud which
files written since the first mark it absorbed.

Raising an existing project to `strict` is a deliberate later step, taken once
the debt is under a baseline, and it is one line in `.craft-config.yml`.

With `guided: true`, every quality gate block gains a plain-language paragraph explaining why the rule exists and where to read more. Turn it off later by flipping the key.

### Step C: Show the derived config before writing it

Same contract as the rest of this skill: display what was inferred, wait for confirmation, then write. What is displayed and written is the project file of [The configuration file (v4)](#the-configuration-file-v4), with the stack detected as that section says and the `strictness` and `guided` the four questions produced. Then validate it and read it back as that section says.

### Step D: Take the baseline

The baseline is the photograph of the code as it is today. It is what lets the plugin demand better without punishing anyone for debt they inherited.

```bash
bash "$(craftsman-path bin/craftsman-ci)" baseline src
```

Pass the source directories the project actually uses (`src`, `app`, `lib`, `packages/*/src`), from the repository root. This is the canonical mark, the one the hooks and CI read: it scans with the same validators and severities, records the rule violations each file already carries, and takes the structural photograph in the same `.craftsman-baseline.json`. `ratchet.py init` alone is not a substitute: it records the structure and no rule, so every inherited violation still blocks the first edit.

- **New project**: the baseline is empty, so the very first file is already held to the full standard. Zero tolerance costs nothing when there is nothing to fix.
- **Existing project**: every violation already there is recorded. From then on it is reported as a warning and no longer blocks; a new one, or one more of the same rule in the same file, still blocks. A file that gets structurally worse than its photograph is reported, and improving one updates its entry. Legacy is never punished for debt it already had.
- **Already taken**: the mark is taken once. When `.craftsman-baseline.json` exists the command refuses and exits 1; leave it as it is and tell the user. Re-taking it is their decision (`--re-baseline --reason "..."`), never a setup default.

Then tell the user, explicitly:

```
.craftsman-baseline.json must be committed. It is the shared reference:
without it in git, CI and your teammates measure against a different photograph.
```

### Step E: `--quick` skips the questions

`--quick` bypasses the four questions entirely. It keeps the observed defaults
and still runs Step D, so a quick setup ends with a valid
`.craftsman-baseline.json` like any other.

Its strictness follows the same rule as the questions, and it does not need to
be re-derived: `config_default_strictness` in `hooks/lib/config.sh` is the one
implementation, and `config_strictness` already falls back to it. The table
above documents what that function returns; it does not compute it.

---

## The configuration file (v4)

Every mode writes this one format, the one `schemas/craft-config.schema.json`
describes and `hooks/lib/config.sh` reads. The project file is
`$PWD/.craft-config.yml`: stack, strictness and guidance describe this
repository, not the machine.

```yaml
# .craft-config.yml, format v4 (schemas/craft-config.schema.json)
v: 4
stack: {stack}
strictness: {strictness}
guided: {guided}
```

- `{stack}`: `symfony` when only `composer.json` exists, `react` when only
  `package.json` exists, `fullstack` when both do, `other` when neither does.
  One word on the same line: the resolver reads a scalar.
- `{strictness}`: `strict`, `moderate` or `relaxed`, from the Step B mapping.
  `--quick` omits the line, and the plugin then derives it
  (`config_default_strictness`).
- `{guided}`: `true` or `false` (question 4). `--quick` writes `false`.

Never write `version:`, a `stack:` mapping of versions, a `packs:` mapping or
a `rules:` block of booleans: that is the format before v4. No consumer reads
the first three (every shipped pack loads on every stack and judges its own
file types), a `stack:` mapping leaves the resolver with no stack at all, and
`rules:` is read as rule-id overrides (`PHP001: warn`), never as switches.

The machine-wide keys live in `~/.claude/.craft-config.yml` and only the
machine owner sets them: `preferred_tools` (`--global`), `trust_project_tools`,
`hooks`, `packs: external`. A project file cannot grant them.

**Validate, then read it back.** A file that parses is not a file the plugin
reads as intended. Before saying setup is done, run the validator (schema,
resolver's own reader) and show the user the values the plugin will use:

```bash
bash -c 'source "$(craftsman-path hooks/lib/config.sh)"; config_validate .craft-config.yml && echo "stack=$(config_stack) strictness=$(config_strictness)"'
```

Any line it prints is a problem to fix before finishing; the healthcheck
reports the same problems as a config error.

**Migrating a pre-v4 file.** A `.craft-config.yml` without `v: 4` was written
for an older format. Keep what the resolver reads (`strictness`, rule-id
overrides under `rules:`, `sentry_org`, `sentry_project`, `context_budget`,
`guided`, and in the global file the machine-owner keys above, `packs:
external` included), replace a `stack:` mapping with the detected word, drop
`version:`, the version numbers and the `packs:` switches, add `v: 4`, show
the result, write it after confirmation, and validate it as above.

---

## Quick Mode (`--quick`)

When `$ARGUMENTS` contains `--quick`, skip ALL interactive questions and auto-generate configuration:

### Process

1. **Detect stack** using Glob tool:
   - `Glob("composer.json")` → PHP detected
   - `Glob("package.json")` → Node detected
   - Map it to `{stack}` as [The configuration file (v4)](#the-configuration-file-v4) says: PHP only → `symfony`, Node only → `react`, both → `fullstack`, neither → `other`

2. **Extract user name** from git, for the summary:
   - Run `git config user.name` via Bash tool
   - Fallback: `"Developer"` if not configured

3. **Write the project file** with the `Write` tool: `$PWD/.craft-config.yml`, the v4 block of [The configuration file (v4)](#the-configuration-file-v4), with the detected stack, `guided: false`, and no `strictness` line (the plugin derives it with `config_default_strictness`).

4. **Take the baseline** exactly as [Step D](#step-d-take-the-baseline) says.

5. **Validate and read back** with the command of [The configuration file (v4)](#the-configuration-file-v4). Report its values, not the ones you meant to write.

6. **Display summary** (no questions asked):

```
Quick Setup Complete!

  Name: {name} (from git config)
  Stack: {stack read back by config_stack}
  Strictness: {strictness read back by config_strictness}
  Biases: all enabled
  Baseline: {what Step D recorded, or "already taken"}

Config saved to .craft-config.yml (this project)
Run /craftsman:setup for full customization (situational questions, DISC profile)
```

### Guard: Existing Config

If `$PWD/.craft-config.yml` already exists (the workshop profile in `~/.claude/` is not a project config and does not stop a project setup):

```
Config already exists at {path}. Quick setup skipped.
Use /craftsman:setup --quick --force to overwrite, or /craftsman:setup for interactive reconfiguration.
```

Exit without changes unless `--force` is also present in `$ARGUMENTS`. A file without `v: 4` is a pre-v4 config: say so and offer the migration of [The configuration file (v4)](#the-configuration-file-v4) instead of skipping silently.

---

You are the **AI Craftsman setup assistant**. Your role is to guide the user through initial configuration and onboarding.

## Welcome (First-time users)

If no `.craft-config.yml` exists in `$PWD` or `~/.claude/`:

```
Welcome to AI Craftsman Superpowers!

You now have a Senior Craftsman methodology baked into your Claude Code.

Here's what's included:
- 15 core skills (DDD, TDD, debugging, planning, scaffolding...)
- 5 core agents + pack-specific specialists
- Real-time code quality hooks with pack-based validators
- Quality metrics dashboard
- Team collaboration system
```

## Pre-check

### Auto-Detection

Before anything else, detect the project stack and available tooling:

Use the **Glob** tool to detect the project stack and available tooling:
- `Glob("composer.json")` → if exists, PHP_DETECTED=true
- `Glob("package.json")` → if exists, NODE_DETECTED=true
- `Glob("vendor/bin/phpstan")` → if exists, PHPSTAN=available, else missing
- `Glob("vendor/bin/deptrac")` → if exists, DEPTRAC=available, else missing

Use the **Bash** tool with simple commands to check CLI tools:
- `command -v npx` → if found, NPX=available, else missing

### Analysis Tools Check

Based on detection results, suggest any missing quality tools before setup continues:

- PHPStan missing → "Consider installing: `composer require --dev phpstan/phpstan`"
- ESLint not configured → "Consider installing: `npm install --save-dev eslint`"
- Deptrac missing (PHP project) → "Consider installing: `composer require --dev qossmic/deptrac`"

Display detected tools so the user knows what's available.

### Stack Pre-Selection

Pre-select the stack based on detection (user can override in Step 4), with the mapping of [The configuration file (v4)](#the-configuration-file-v4):

- PHP detected → `symfony`
- Node detected → `react`
- Both detected → `fullstack`, display confirmation prompt
- Neither → `other`

### Existing Config Check

Check if configuration already exists:

Use the **Read** tool to read `$PWD/.craft-config.yml` (this project) and `~/.claude/.craft-config.yml` (this machine). A missing file is CONFIG_NOT_FOUND for that scope.

- If the project file exists: Show it and ask "Do you want to reconfigure? [y/N]". Without `v: 4` it is a pre-v4 file: propose the migration of [The configuration file (v4)](#the-configuration-file-v4).
- If it doesn't exist: Proceed with full setup

## Setup Process

### Step 1: Welcome

Display:

```
Welcome to AI Craftsman Superpowers!

Let's configure your craftsman profile.
The project settings go to .craft-config.yml (this project),
your personal profile to ~/.claude/.craft-config.yml (this machine).
```

### Step 2: Profile Information

Use `AskUserQuestion` to collect:

**Question 1 - Name:**
Ask for the user's name (free text via "Other" option).

**Question 2 - DISC Profile Method:**
Present these options:
- **I know my DISC** - Direct selection
- **Mini-test (4 questions)** - Quick assessment
- **Skip this step** - Configure later

---

#### If "I know my DISC" selected:

Present direct choice:
- **DI** - Dominant-Influential: Direct + Enthusiastic
- **D** - Dominant: Direct, results-focused, decisive
- **I** - Influential: Enthusiastic, collaborative, optimistic
- **C** - Conscientious: Analytical, detail-oriented, systematic
- Other (for S, DC, IS, SC combinations)

---

#### If "Mini-test" selected:

Run the 4-question DISC assessment:

**Q1 - Problem Solving:**
```
When facing a technical problem, you prefer to:
```
- **A) Act fast** - Adjust along the way
- **B) Analyze first** - Understand before acting

**Q2 - Meetings:**
```
In meetings, you prefer to:
```
- **A) Get to the point** - Decide quickly
- **B) Build consensus** - Let everyone speak

**Q3 - Giving feedback:**
```
When a colleague makes a mistake, you:
```
- **A) Tell them directly** - What went wrong
- **B) Choose your words carefully** - Take time to formulate

**Q4 - Receiving feedback:**
```
You prefer feedback that is:
```
- **A) Direct and factual** - Even if it stings
- **B) Constructive** - Encouraging

**Scoring Algorithm:**

| Q1 | Q2 | Q3 | Q4 | Result |
|----|----|----|----|----|
| A | A | A | A | **D** (Dominant) |
| A | A | A | B | **DI** |
| A | A | B | A | **DC** |
| A | A | B | B | **DI** |
| A | B | A | A | **DI** |
| A | B | A | B | **I** (Influential) |
| A | B | B | A | **DC** |
| A | B | B | B | **I** |
| B | A | A | A | **DC** |
| B | A | A | B | **C** (Conscientious) |
| B | A | B | A | **C** |
| B | A | B | B | **SC** |
| B | B | A | A | **IS** |
| B | B | A | B | **I** |
| B | B | B | A | **SC** |
| B | B | B | B | **S** (Steady) |

After scoring, display:
```
Based on your answers, your DISC profile is: {result}

{description of the profile}

This helps me adapt my communication style to work better with you.
```

**Profile Descriptions:**
- **D (Dominant)**: You like getting straight to the point, making quick decisions, and seeing concrete results.
- **I (Influential)**: You enjoy collaboration, enthusiasm, and getting others excited about your ideas.
- **S (Steady)**: You value stability, listening, and harmonious teamwork.
- **C (Conscientious)**: You prioritize precision, thorough analysis, and high standards.
- **DI**: Direct AND enthusiastic - you want results while bringing the team along.
- **DC**: Direct AND analytical - you want results backed by solid facts.
- **IS**: Collaborative AND steady - you create a positive and reliable work environment.
- **SC**: Steady AND analytical - you combine patience with methodical rigor.

---

#### If "Skip" selected:

Set `disc_type: ""` (empty) and continue. Display:
```
No problem! You can set your DISC profile later by running /craftsman:setup again.
```

### Step 3: Bias Protection

Use `AskUserQuestion` with `multiSelect: true`:

**Question 3 - Biases to monitor:**
- **Acceleration** - Warns when rushing to code before understanding
- **Scope Creep** - Warns when adding features beyond original scope
- **Over-optimization** - Warns when abstracting prematurely
- **Dispersion** - Warns when jumping between topics

Default recommendation: All enabled. Record the answers by id: `acceleration`, `scope_creep`, `over_optimization`, `dispersion`.

### Step 4: Stack

Detect available packs and their descriptions:

Use the **Glob** tool: `Glob("packs/*/pack.yml")`. For each found file, use the **Read** tool to read it and extract the `description:` field. Display each pack as `- **<pack-name>**: <description>`. If no packs found, say "No packs found." Every shipped pack declares `stack: ["*"]` and judges its own file types, so there is nothing to switch on or off: the question is which stack this project is.

Use `AskUserQuestion` to confirm the stack pre-selected in Pre-check:

**Question 4 - Stack:**
- **symfony** - PHP/Symfony - _pre-selected if only PHP detected_
- **react** - React/TypeScript - _pre-selected if only Node detected_
- **fullstack** - both - _pre-selected if both detected_
- **other** - anything else

### Step 5: Generate Configuration

Two files, each with its own scope:

1. **This project**: write `$PWD/.craft-config.yml` with the v4 block of [The configuration file (v4)](#the-configuration-file-v4). Without the situational questions of Step B, omit `strictness` (the plugin derives it) and write `guided: false`.
2. **This machine**: merge the personal profile into `~/.claude/.craft-config.yml`. Add `v: 4` if it is absent, add or replace the `profile:` block, and keep every other key: that file also holds the machine owner's switches (`trust_project_tools`, `hooks`, `packs: external`).

```yaml
# ~/.claude/.craft-config.yml, merged: every other key is kept
v: 4
profile:
  name: "{collected_name}"
  disc_type: "{collected_disc}"
  biases:
    - {bias1}
    - {bias2}
```

Use the `Write` tool (or `Edit` for the merge), then validate and read back both files with the command of [The configuration file (v4)](#the-configuration-file-v4) (`config_validate ~/.claude/.craft-config.yml` for the second). Take the baseline as [Step D](#step-d-take-the-baseline) says.

### Step 6: Display Summary

After saving, display the values read back, not the ones you meant to write:

```
Configuration saved:
  .craft-config.yml (this project)
  ~/.claude/.craft-config.yml (your profile)

Your Profile:
  Name: {name}
  DISC Type: {disc_type}
  Bias Protection: {biases}

This Project:
  Stack: {stack read back by config_stack}
  Strictness: {strictness read back by config_strictness}
  Baseline: {what Step D recorded, or "already taken"}

Available Commands:

Core (20 skills, always available):
  /craftsman:challenge - Architecture review
  /craftsman:ci        - CI/CD integration
  /craftsman:debug     - Systematic debugging
  /craftsman:design    - DDD design with challenge phases
  /craftsman:git       - Safe git workflow
  /craftsman:metrics   - Quality metrics dashboard
  /craftsman:parallel  - Parallel execution
  /craftsman:plan      - Structured planning
  /craftsman:refactor  - Systematic refactoring
  /craftsman:scaffold  - Unified scaffolding
  /craftsman:setup     - Configuration wizard (re-run anytime)
  /craftsman:spec      - Specification-first (TDD)
  /craftsman:team      - Assemble agent teams
  /craftsman:test      - Pragmatic testing
  /craftsman:verify    - Evidence-based verification

{if stack is symfony or fullstack}
Symfony Pack:
  /craftsman:scaffold [entity|usecase]  - Scaffold DDD patterns
{/if}

{if stack is react or fullstack}
React Pack:
  /craftsman:scaffold [component|hook]  - Scaffold React patterns
{/if}

AI-ML Pack (every stack):
  /craftsman:rag          - Design RAG pipeline
  /craftsman:mlops        - MLOps audit
  /craftsman:agent-design - Agent 3P pattern

Happy crafting!
```

## Important Notes

- Always use `AskUserQuestion` for interactive collection
- Use `Write` tool to create the config file
- Validate the written file with `config_validate`, not only its YAML syntax: a pre-v4 file parses and is still read wrongly
- If reconfiguring, preserve rule-id overrides under `rules:` and every key of the global file the user added manually

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.