From kraftwork
Provider-aware workspace configuration wizard — idempotent and incremental.
How this skill is triggered — by the user, by Claude, or both
Slash command
/kraftwork:kraft-configThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Set up or reconfigure a development workspace by discovering installed providers, collecting provider-specific config, and scaffolding the workspace directory structure.
Set up or reconfigure a development workspace by discovering installed providers, collecting provider-specific config, and scaffolding the workspace directory structure.
jq for JSON parsinggit installedIMPORTANT: Derive the scripts directory from this skill file's location:
kraftwork/skills/kraft-config/SKILL.md<workspace-root>/scripts/When you load this skill, note its file path and compute the scripts directory. For example, if this skill is at /path/to/kraftwork/skills/kraft-config/SKILL.md, then scripts are at /path/to/kraftwork/scripts/.
Read ~/.claude/settings.json and extract the enabledPlugins object. Keys are formatted as pluginName@marketplace, values are booleans. If enabledPlugins is absent, treat all cached plugins as enabled.
SETTINGS="$HOME/.claude/settings.json"
CACHE_DIR="$HOME/.claude/plugins/cache"
ENABLED_PLUGINS=$(jq -r '.enabledPlugins // {} | to_entries[] | select(.value == true) | .key' "$SETTINGS")
For each enabled kraftwork-* plugin, check for a providers.json at:
~/.claude/plugins/cache/<marketplace>/<pluginName>/<version>/providers.json
The <version> directory is whichever single directory exists under the plugin name.
PROVIDERS_BY_CATEGORY=()
for ENTRY in $ENABLED_PLUGINS; do
PLUGIN_NAME="${ENTRY%%@*}"
MARKETPLACE="${ENTRY##*@}"
# Only process kraftwork-* plugins
[[ "$PLUGIN_NAME" == kraftwork-* ]] || continue
PLUGIN_DIR="$CACHE_DIR/$MARKETPLACE/$PLUGIN_NAME"
[ -d "$PLUGIN_DIR" ] || continue
VERSION_DIR=$(ls -1 "$PLUGIN_DIR" | head -1)
PROVIDERS_FILE="$PLUGIN_DIR/$VERSION_DIR/providers.json"
if [ -f "$PROVIDERS_FILE" ]; then
echo "Found providers: $PLUGIN_NAME ($PROVIDERS_FILE)"
fi
done
Parse each providers.json and collect provider declarations grouped by category. A providers.json lists which categories a plugin handles, for example:
[
{ "category": "git-hosting", "plugin": "kraftwork-gitlab" },
{ "category": "ticket-management", "plugin": "kraftwork-jira" }
]
The six categories are: git-hosting, ci, ticket-management, document-storage, memory, messaging.
Each category has different fallback behaviour when the user has no external provider:
| Category | Local fallback | Fallback provider |
|---|---|---|
ticket-management | Full — markdown files in workspace | kraftwork-local |
document-storage | Full — filesystem under workspace | kraftwork-local |
memory | Degraded — markdown files, grep-based recall | kraftwork-local |
ci | Partial — local test/build commands | kraftwork-local |
git-hosting | None — category skipped | (omitted from workspace.json) |
messaging | None — category skipped | (omitted from workspace.json) |
For each category:
kraftwork-local or skip. Explain what the local fallback provides.kraftwork-local.Always include kraftwork-local as an explicit option for categories that support it.
Kraftwork requires the superpowers plugin. Check that it is installed and enabled:
SUPERPOWERS_INSTALLED=$(echo "$ENABLED_PLUGINS" | grep -c "^superpowers@" || true)
if [ "$SUPERPOWERS_INSTALLED" -eq 0 ]; then
echo "WARNING: The 'superpowers' plugin is required by Kraftwork but is not installed."
echo "Install it with: claude plugin install superpowers"
echo ""
echo "Kraftwork uses superpowers for brainstorming, planning, TDD, and debugging workflows."
echo "You can continue setup, but orchestrator skills will not function correctly without it."
fi
Warn but do not block — the user may install it later.
For each selected provider that is not kraftwork-local:
config/workspace-config.json:PLUGIN_DIR="$CACHE_DIR/$MARKETPLACE/$PLUGIN_NAME"
VERSION_DIR=$(ls -1 "$PLUGIN_DIR" | head -1)
SCHEMA_FILE="$PLUGIN_DIR/$VERSION_DIR/config/workspace-config.json"
If the schema exists, present each field to the user using the prompt text as conversational guidance and example as illustration.
Collect responses and store them internally — provider config is handled by the extension, not written to workspace.json.
Field type handling:
string fields: Ask and accept a single value.boolean fields: Ask as a yes/no question.string[] fields: Accept comma-separated values or one at a time.required: false or required absent): Accept blank/skip. If skipped, omit the field entirely — do not write null.Read the core workspace schema from this skill's plugin root at config/workspace-config.json. Prompt for each field defined there:
workspace.name — the workspace nameworkspace.path — the workspace root directoryInfer a smart default for path from the current directory:
echo "Current directory: $(pwd)"
Assemble the full workspace.json and show a preview before writing:
Here is the workspace.json that will be written:
{
"configVersion": 3,
"workspace": { ... },
"providers": {
"git-hosting": "kraftwork-gitlab",
"ci": "kraftwork-local",
"ticket-management": "kraftwork-jira",
"document-storage": "kraftwork-local",
"memory": "kraftwork-local"
}
}
Does this look right?
Categories not configured will be omitted from the providers object.
Wait for confirmation. If the user requests changes, re-prompt for the specific fields they want to adjust.
Write workspace.json with "configVersion": 3 as the first key, at the workspace root path. The providers object maps each configured category to its plugin name as a plain string. Omit unconfigured categories entirely.
WORKSPACE=$(jq -r '.workspace.path' workspace.json)
WORKSPACE="${WORKSPACE/#\~/$HOME}"
# Initialise as git repo if not already one
git -C "$WORKSPACE" rev-parse --git-dir 2>/dev/null || git init "$WORKSPACE"
mkdir -p "$WORKSPACE/modules"
mkdir -p "$WORKSPACE/trees"
# .gitignore with trees/ entry
if [ ! -f "$WORKSPACE/.gitignore" ]; then
echo "trees/" > "$WORKSPACE/.gitignore"
elif ! grep -q "^trees/$" "$WORKSPACE/.gitignore"; then
echo "trees/" >> "$WORKSPACE/.gitignore"
fi
Do NOT create docs/ — it is created lazily by the document storage provider on first use.
This phase runs only when git-hosting is configured in workspace.json.
GIT_PROVIDER=$(jq -r '.providers["git-hosting"] // empty' workspace.json)
If configured, ask the user which repositories to clone. For each repo:
$WORKSPACE/modules/<repo> already exists.{git-hosting}:git-hosting-import with the repo name and target path $WORKSPACE/modules/<repo>.If no git-hosting provider is configured, skip this phase and inform the user they can clone repos manually into modules/.
If $WORKSPACE/CLAUDE.md does not already exist, generate it with:
modules/, trees/, docs/)All values must come from workspace.json. Do not hardcode any company name, URLs, or repository names.
If workspace.json already exists:
configVersion:
providers.<category>.plugin format to providers.<category> (direct string)configVersion: 3kraftwork-* plugins that have appeared since the last run.If nothing is missing or changed, report "Config up to date" and exit.
After all phases, show a summary:
Workspace configured at $WORKSPACE
Providers:
<category>: <plugin> (one line per configured category)
Skipped: <comma-separated list of unconfigured categories, or "none">
Structure:
$WORKSPACE/
├── modules/ (<N> repos)
├── trees/ (git worktrees — gitignored)
└── docs/ (created on first use by document storage provider)
Next steps:
1. cd "$WORKSPACE"
2. Run /kraft-work TICKET-123 to begin work on a ticket
3. Run /kraft-sync to update all repos
npx claudepluginhub filipeestacio/kraftwork --plugin kraftworkInitializes project configuration by auto-detecting framework, replacing CLAUDE.md placeholders, and installing rules, hooks, and scripts.
Bootstraps .claude/ dotclaude config from template if missing, then customizes all files to match project's tech stack, conventions, and patterns. Interactive via user confirmations.
Configure Claude Code for this project - detects languages and sets up rules, skills, and validators