Skip to content

Commit 218462c

Browse files
committed
Tool profile: dev-loop config paths + active setup guidance
The capability-role tool profile (knowledge/verify/explore/tacit/design/intake) carried over from loop-orchestrator but was under-surfaced and stale-named. - Rename config paths to dev-loop: ~/.claude/dev-loop/tools.json (global) and <repo>/.dev-loop/tools.json (per-repo), plus DEV_LOOP_CONFIG_HOME/PROJECT env. The old loop-orchestrator paths + LOOP_ORCH_* env are still read as a fallback, so existing configs keep working (bats tests use the legacy env → still pass). - Add /dev-loop:configure skill — maps your wiki (knowledge), test command (verify), code search (explore), etc. to real tools and writes tools.json. - Add hooks/config-nudge.sh (SessionStart) — nudges toward /dev-loop:configure only when nothing is configured, at most weekly, then silent once set; kill switch DEV_LOOP_CONFIG_NUDGE=0. - tool-profile.md + README document the paths, the configure skill, and the nudge. Bump 0.3.0 -> 0.4.0.
1 parent 3012566 commit 218462c

8 files changed

Lines changed: 209 additions & 16 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"url": "https://github.com/choiyounggi/dev-loop.git"
2121
},
2222
"homepage": "https://github.com/choiyounggi/dev-loop",
23-
"version": "0.3.0",
23+
"version": "0.4.0",
2424
"tags": [
2525
"orchestrator",
2626
"verification-loop",

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "dev-loop",
33
"description": "loop-orchestrator's verification loop (TDD / PDCA / Reflexion) with the plan step FIXED to a wiki-grounded planning methodology (wiki-plan): every design decision is routed to a bundled semantic-layer wiki before code is written. Adds a knowledge-capture loop — sessions emit verified insights, and knowledge-flush researches, dedups, routes, and opens a wiki PR for owner review.",
4-
"version": "0.3.0",
4+
"version": "0.4.0",
55
"author": {
66
"name": "choiyounggi",
77
"url": "https://github.com/choiyounggi"

README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,31 @@ an ingest candidate. This is not a configurable role and cannot be turned off.
6565
The wiki lives at the plugin root (`wiki/`, `INDEX.md`, `AGENTS.md`,
6666
`templates/`); the wiki skills resolve their paths against `${CLAUDE_PLUGIN_ROOT}`.
6767

68+
### Configuring your tools (optional)
69+
70+
Like loop-orchestrator, dev-loop runs fully generic with **no** config, but you
71+
can map its **capability roles** to your real tools so the loop uses them:
72+
73+
| Role | Map to |
74+
|------|--------|
75+
| `verify` | your project's **test / build / QA** command (the loop's run step) |
76+
| `knowledge` | your domain/team **wiki** or knowledge MCP (external facts) |
77+
| `explore` | code/symbol search (LSP, ripgrep, a source-search CLI) |
78+
| `tacit` | past incidents / danger-zone lore |
79+
| `design` | Figma / visual-spec MCP (UI work) |
80+
| `intake` | issue tracker (orchestrate's work-list) |
81+
82+
(`plan` is **not** a role — the plan step is fixed to `wiki-plan`. And the bundled
83+
best-practice `wiki/` needs no config; `knowledge` is a *separate* external wiki.)
84+
85+
Set it up with **`/dev-loop:configure`**, which writes `~/.claude/dev-loop/tools.json`
86+
(global) or `<repo>/.dev-loop/tools.json` (per-repo, team-shared). Precedence is
87+
git-config style: `defaults < ~/.claude/dev-loop/tools.json < <repo>/.dev-loop/tools.json`.
88+
A SessionStart hook nudges you (at most weekly, then never) if you haven't
89+
configured anything — silence it with `DEV_LOOP_CONFIG_NUDGE=0`. Legacy
90+
`loop-orchestrator` config paths are still read as a fallback. See
91+
`references/tool-profile.md` and `examples/tools.example.json`.
92+
6893
---
6994

7095
## The knowledge-capture loop
@@ -126,6 +151,7 @@ it never interferes with ordinary `gh pr create` in any repo.
126151
| `wiki-query` | Answer a question from the wiki with citations. |
127152
| `wiki-lint` | Health-check the wiki. |
128153
| `knowledge-flush` | Research + verify + route queued insights → one reviewed wiki PR. |
154+
| `configure` | Set up the capability-role tool profile (map your wiki, test command, etc.). |
129155

130156
## Structure
131157

@@ -134,12 +160,13 @@ dev-loop/
134160
├── .claude-plugin/{plugin,marketplace}.json
135161
├── AGENTS.md INDEX.md templates/ # wiki schema + routing entry + page template
136162
├── wiki/ # 10-domain semantic-layer knowledge base
137-
├── skills/ # the 7 skills above
163+
├── skills/ # the 8 skills above
138164
├── agents/test-quality-auditor.md # bundled independent test auditor (loop step 6.5)
139165
├── hooks/
140166
│ ├── hooks.json
141167
│ ├── preflight.sh # SessionStart: git/tmux/jq advisory
142168
│ ├── insight-instruction.sh # SessionStart: inject ★ Insight capture instruction (global)
169+
│ ├── config-nudge.sh # SessionStart: nudge to /dev-loop:configure if unconfigured (weekly)
143170
│ ├── loop-gate.sh # Stop: verification-loop integrity gate
144171
│ ├── harvest-insights.sh + harvest.js # Stop: harvest insights → queue
145172
│ ├── auto-flush.sh # Stop: auto-run knowledge-flush (guarded) → PR

hooks/config-nudge.sh

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env bash
2+
# dev-loop — SessionStart: gently nudge the user to configure the tool profile
3+
# (knowledge=wiki, verify=test command, …) IF they haven't yet.
4+
#
5+
# Fires only when no tools.json is configured anywhere, and at most once a week
6+
# (a marker suppresses it) so it never nags. Once configured, it goes silent.
7+
# Disable entirely with DEV_LOOP_CONFIG_NUDGE=0.
8+
set +e
9+
10+
[ "${DEV_LOOP_CONFIG_NUDGE:-1}" = "0" ] && exit 0
11+
12+
# Don't nudge inside the flush working checkout.
13+
case "${CLAUDE_PROJECT_DIR:-$PWD}" in
14+
"$HOME/.dev-loop/repo"*) exit 0 ;;
15+
esac
16+
17+
PROJ="${CLAUDE_PROJECT_DIR:-$PWD}"
18+
19+
# Already configured? (dev-loop or legacy path, global or per-repo, or env.)
20+
configured=0
21+
for f in \
22+
"$HOME/.claude/dev-loop/tools.json" \
23+
"$HOME/.claude/loop-orchestrator/tools.json" \
24+
"$PROJ/.dev-loop/tools.json" \
25+
"$PROJ/.loop-orchestrator/tools.json" \
26+
"${DEV_LOOP_CONFIG_HOME:-}" "${LOOP_ORCH_CONFIG_HOME:-}" \
27+
"${DEV_LOOP_CONFIG_PROJECT:-}" "${LOOP_ORCH_CONFIG_PROJECT:-}"; do
28+
[ -n "$f" ] && [ -f "$f" ] && { configured=1; break; }
29+
done
30+
[ "$configured" -eq 1 ] && exit 0
31+
32+
# Rate-limit: skip if nudged within the last 7 days.
33+
MARK="$HOME/.dev-loop/.config-nudged"
34+
if [ -f "$MARK" ] && [ -n "$(find "$MARK" -mtime -7 2>/dev/null)" ]; then
35+
exit 0
36+
fi
37+
mkdir -p "$HOME/.dev-loop" 2>/dev/null
38+
touch "$MARK" 2>/dev/null
39+
40+
read -r -d '' MSG <<'EOF'
41+
# dev-loop — optional one-time setup
42+
43+
dev-loop works with zero config, but you'll get more out of it by mapping its
44+
capability roles to your real tools. Notably:
45+
• `verify` → your project's actual test / build command (used in the loop's run step)
46+
• `knowledge` → your domain/team wiki or knowledge MCP (external facts — the bundled best-practice wiki needs no setup)
47+
• also: `explore` (code search), `tacit` (incidents), `design` (Figma)
48+
49+
Run **/dev-loop:configure** to set these up (writes ~/.claude/dev-loop/tools.json,
50+
or <repo>/.dev-loop/tools.json for a team-shared, per-repo profile).
51+
52+
(This reminder shows at most weekly until you configure, then stops. Silence it
53+
now with DEV_LOOP_CONFIG_NUDGE=0.)
54+
EOF
55+
56+
printf '%s' "$MSG" | node -e '
57+
const fs=require("fs");let s="";try{s=fs.readFileSync(0,"utf8")}catch{}
58+
process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:s}}));
59+
' 2>/dev/null
60+
61+
exit 0

hooks/hooks.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
{
1313
"type": "command",
1414
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/insight-instruction.sh"
15+
},
16+
{
17+
"type": "command",
18+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/config-nudge.sh"
1519
}
1620
]
1721
}

references/tool-profile.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,17 @@ and tends to drag in an environment-specific tool's own assumptions.
8888
Layered like `git config`, lowest to highest:
8989

9090
```
91-
built-in defaults < ~/.claude/loop-orchestrator/tools.json < <repo>/.loop-orchestrator/tools.json
91+
built-in defaults < ~/.claude/dev-loop/tools.json < <repo>/.dev-loop/tools.json
9292
```
9393

94-
- **per-user** (`~/.claude/loop-orchestrator/tools.json`) — your machine's tools,
95-
applied across every project you run the orchestrator in.
96-
- **per-repo** (`<repo>/.loop-orchestrator/tools.json`) — commit it to share a
94+
Run **`/dev-loop:configure`** to set these up interactively (it maps your wiki,
95+
test command, etc. and writes the file). The legacy `loop-orchestrator` paths
96+
(`~/.claude/loop-orchestrator/tools.json`, `<repo>/.loop-orchestrator/tools.json`)
97+
are still read as a fallback.
98+
99+
- **per-user** (`~/.claude/dev-loop/tools.json`) — your machine's tools,
100+
applied across every project.
101+
- **per-repo** (`<repo>/.dev-loop/tools.json`) — commit it to share a
97102
team-standard mapping; overrides your per-user file.
98103
- Merge is **per role and per field**: a per-repo file can override one role — or
99104
one field of a role — and inherit the rest. To drop an inherited value, set that

scripts/resolve-tools.sh

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
#!/bin/sh
2-
# resolve-tools.sh — resolve the loop-orchestrator tool profile by layering
2+
# resolve-tools.sh — resolve the dev-loop tool profile by layering
33
# config files over built-in defaults (git-config style precedence):
44
#
5-
# built-in defaults < ~/.claude/loop-orchestrator/tools.json < <repo>/.loop-orchestrator/tools.json
5+
# built-in defaults < ~/.claude/dev-loop/tools.json < <repo>/.dev-loop/tools.json
6+
#
7+
# (The old loop-orchestrator paths — ~/.claude/loop-orchestrator/tools.json and
8+
# <repo>/.loop-orchestrator/tools.json — are still read as a fallback so existing
9+
# configs keep working after the rename.)
610
#
711
# Each capability role (intake / knowledge / tacit / verify / explore /
812
# design, plus any custom role) is merged independently and field-wise, so a project file can
@@ -19,10 +23,11 @@
1923
# resolve-tools.sh --role verify # print just the resolved object for one role
2024
#
2125
# env overrides (mainly for tests / non-standard layouts):
22-
# LOOP_ORCH_CONFIG_HOME per-user config path
23-
# (default: ~/.claude/loop-orchestrator/tools.json)
24-
# LOOP_ORCH_CONFIG_PROJECT per-repo config path
25-
# (default: <git-root-or-PWD>/.loop-orchestrator/tools.json)
26+
# DEV_LOOP_CONFIG_HOME per-user config path
27+
# (default: ~/.claude/dev-loop/tools.json)
28+
# DEV_LOOP_CONFIG_PROJECT per-repo config path
29+
# (default: <git-root-or-PWD>/.dev-loop/tools.json)
30+
# LOOP_ORCH_CONFIG_HOME / LOOP_ORCH_CONFIG_PROJECT — legacy fallbacks (still honored)
2631
set -eu
2732

2833
JQ=$(command -v jq) || { echo "resolve-tools: jq not found" >&2; exit 127; }
@@ -38,12 +43,34 @@ DEFAULTS='{
3843
"design": {"kind":"default","when":"visual/UI spec for FE/UI tasks, e.g. a Figma link in the issue — read the referenced design before implementing (orchestrate Phase 0/2; loop-implement step 1)"}
3944
}'
4045

41-
home_cfg="${LOOP_ORCH_CONFIG_HOME:-$HOME/.claude/loop-orchestrator/tools.json}"
42-
if [ -n "${LOOP_ORCH_CONFIG_PROJECT:-}" ]; then
46+
# Per-user config: explicit env wins; else the dev-loop path; else the legacy
47+
# loop-orchestrator path if it exists; else the canonical dev-loop path.
48+
if [ -n "${DEV_LOOP_CONFIG_HOME:-}" ]; then
49+
home_cfg="$DEV_LOOP_CONFIG_HOME"
50+
elif [ -n "${LOOP_ORCH_CONFIG_HOME:-}" ]; then
51+
home_cfg="$LOOP_ORCH_CONFIG_HOME"
52+
elif [ -f "$HOME/.claude/dev-loop/tools.json" ]; then
53+
home_cfg="$HOME/.claude/dev-loop/tools.json"
54+
elif [ -f "$HOME/.claude/loop-orchestrator/tools.json" ]; then
55+
home_cfg="$HOME/.claude/loop-orchestrator/tools.json"
56+
else
57+
home_cfg="$HOME/.claude/dev-loop/tools.json"
58+
fi
59+
60+
# Per-repo config: same precedence, resolved against the repo root.
61+
if [ -n "${DEV_LOOP_CONFIG_PROJECT:-}" ]; then
62+
proj_cfg="$DEV_LOOP_CONFIG_PROJECT"
63+
elif [ -n "${LOOP_ORCH_CONFIG_PROJECT:-}" ]; then
4364
proj_cfg="$LOOP_ORCH_CONFIG_PROJECT"
4465
else
4566
root=$(git rev-parse --show-toplevel 2>/dev/null || pwd -P)
46-
proj_cfg="$root/.loop-orchestrator/tools.json"
67+
if [ -f "$root/.dev-loop/tools.json" ]; then
68+
proj_cfg="$root/.dev-loop/tools.json"
69+
elif [ -f "$root/.loop-orchestrator/tools.json" ]; then
70+
proj_cfg="$root/.loop-orchestrator/tools.json"
71+
else
72+
proj_cfg="$root/.dev-loop/tools.json"
73+
fi
4774
fi
4875

4976
# Load a layer as compact JSON; warn + skip if missing/invalid (fail-open to {}).

skills/configure/SKILL.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
name: configure
3+
description: Set up dev-loop's capability-role tool profile — map `knowledge` (your domain wiki / MCP), `verify` (your project's test/build/QA command), `explore` (code search), `tacit` (past incidents), and `design` (Figma/visual spec) to the actual tools this environment has, then write ~/.claude/dev-loop/tools.json (global) or <repo>/.dev-loop/tools.json (per-repo). Use when asked to "configure dev-loop", "set up tools", "map my wiki/test command", or "/dev-loop:configure".
4+
---
5+
6+
# configure — set up the dev-loop tool profile
7+
8+
dev-loop runs fully generic with **no** config (every role falls back to the
9+
model's own behavior). Configuring the roles makes the loop use *your* real tools:
10+
your domain wiki for facts, your actual test command for verification, etc. The
11+
bundled best-practice `wiki/` (used by `wiki-plan`) needs no config — the
12+
`knowledge` role is for a separate *external/domain* wiki.
13+
14+
> Note: the plan step is fixed to `wiki-plan` and is NOT configurable. There is no
15+
> `plan` role.
16+
17+
## Steps
18+
19+
1. **Show the current profile.** Run and report what is already set vs. default:
20+
```sh
21+
sh ${CLAUDE_PLUGIN_ROOT}/scripts/resolve-tools.sh --summary
22+
```
23+
24+
2. **Decide scope.**
25+
- **Global** (all your projects): `~/.claude/dev-loop/tools.json`
26+
- **Per-repo** (committed, team-shared; overrides global per role/field):
27+
`<repo>/.dev-loop/tools.json`
28+
Ask the user which, if unclear. (Legacy `~/.claude/loop-orchestrator/tools.json`
29+
and `<repo>/.loop-orchestrator/tools.json` are still read as a fallback.)
30+
31+
3. **Map each role to a real tool.** Read `${CLAUDE_PLUGIN_ROOT}/examples/tools.example.json`
32+
as the shape and `references/tool-profile.md` for the schema. For THIS
33+
environment, detect and propose concrete mappings, then confirm with the user:
34+
35+
| Role | Map to | How to find it |
36+
|------|--------|----------------|
37+
| `knowledge` | your domain/policy **wiki** or knowledge MCP | check available MCP servers (e.g. a `wiki_search`/`search_wiki` tool) |
38+
| `verify` | your project's **test / build / QA** command | read `package.json` scripts / Makefile / `pom.xml` / CI config for the real command |
39+
| `explore` | code/symbol search (LSP, `rtb-sourcecode`, ripgrep) | what this repo/language supports |
40+
| `tacit` | past incidents / danger-zone lore (MCP) | check for a lore/incidents MCP |
41+
| `design` | Figma / visual-spec MCP | only if UI work; check for a Figma MCP |
42+
| `intake` | issue tracker (orchestrate work-list) | Jira/GitHub issues MCP, if used |
43+
44+
Leave any role the user has no tool for as `default` (omit it).
45+
`kind` is one of `mcp | skill | agent | cli | default`; add `ref`, and
46+
optionally `how` (invocation hint) and `when` (a one-line trigger).
47+
48+
4. **Write the file** for the chosen scope, e.g. global:
49+
```jsonc
50+
// ~/.claude/dev-loop/tools.json
51+
{
52+
"knowledge": { "kind": "mcp", "ref": "<your-wiki-mcp>", "how": "search -> read", "when": "domain facts, policy, code values" },
53+
"verify": { "kind": "cli", "ref": "<your test/build command>", "how": "run only; report failures verbatim", "when": "step 5 — running tests" }
54+
}
55+
```
56+
Include only the roles being set; unset roles inherit `default`. For `verify`,
57+
map the **exact** command (e.g. `pnpm -w test`, `./gradlew test`) — verified by
58+
reading the project's build config, not guessed.
59+
60+
5. **Validate.** Re-run `resolve-tools.sh --summary` and confirm each role now
61+
resolves as intended (not `default` where you set it). Report the final profile.
62+
63+
## Guardrails
64+
- Never map `verify` (or any role) to a tool that runs its own implement/fix/retry
65+
loop — a role is injected into ONE loop step, never a nested loop (see
66+
`references/tool-profile.md`). `verify` must run tests and report only.
67+
- Do not invent MCP/tool names — only map tools you confirmed exist in this
68+
environment. If unsure, leave the role `default` and say so.
69+
- Never write secrets/tokens into tools.json; reference tools by name only.

0 commit comments

Comments
 (0)