Skip to content

Commit 4fd4f48

Browse files
jwaldripclaude
andcommitted
feat: add provider integration, cowork support, and three-tier instruction merge
- Add built-in provider instruction files (ticketing, spec, design, comms) with default behaviors for each phase of the AI-DLC workflow - Implement three-tier instruction merge: built-in defaults → inline settings.yml instructions → project .ai-dlc/providers/{type}.md overrides - Add provider context injection in session and subagent hooks - Update elaborate skill with Phase 6.5 ticketing sync (epic/ticket creation, DAG → blocked-by mapping, existing epic support) - Add cowork support with clone-first approach for non-repo environments - Update builder/reviewer hats with SHOULD-level ticket status sync - Expand settings schema with per-category provider type enums and instructions field - Rename provider keys: ticketingProvider → ticketing, specProvider → spec, designProvider → design, commsProvider → comms Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 525d608 commit 4fd4f48

File tree

14 files changed

+575
-214
lines changed

14 files changed

+575
-214
lines changed

examples/settings.yml

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,25 @@ git:
3838
# Provider Configuration (optional)
3939
# Configure external system integrations for ticket sync, spec references, and more.
4040
# providers:
41-
# specProvider:
42-
# type: notion # notion | confluence | google-docs
43-
# config:
44-
# workspace_id: "abc123" # Optional provider-specific config
45-
#
46-
# ticketingProvider:
41+
# ticketing:
4742
# type: jira # jira | linear | github-issues | gitlab-issues
4843
# config:
4944
# project_key: "PROJ"
45+
# instructions: |
46+
# - Use Fibonacci story points (1, 2, 3, 5, 8, 13)
47+
# - Always set component to "Backend" or "Frontend"
5048
#
51-
# designProvider:
49+
# design:
5250
# type: figma # figma
51+
# instructions: |
52+
# - Only reference designs marked "Ready for Dev"
53+
#
54+
# spec:
55+
# type: notion # notion | confluence | google-docs
56+
# config:
57+
# workspace_id: "your-workspace-id"
5358
#
54-
# commsProvider:
59+
# comms:
5560
# type: slack # slack | teams | discord
5661
# config:
57-
# channel: "#engineering"
62+
# channel: "#dev-updates"

plugin/hats/builder.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ The Builder implements code to satisfy the Unit's Completion Criteria, using bac
3939
- You SHOULD reference spec provider for API contracts if configured (endpoint definitions, data schemas)
4040
- **Validation**: Can enumerate what needs to be built
4141

42+
#### Provider Sync — Ticket Status
43+
- If a `ticket` field exists in the current unit's frontmatter, **SHOULD** update the ticket status to **In Progress** using the ticketing provider's MCP tools
44+
- If the unit is completed successfully, **SHOULD** update the ticket to **Done**
45+
- If the unit is blocked, **SHOULD** flag the ticket as **Blocked** and add the blocker description as a comment
46+
- If MCP tools are unavailable, skip silently — never block building on ticket updates
47+
4248
2. Implement incrementally
4349
- You MUST work in small, verifiable increments
4450
- You MUST run backpressure checks after each change

plugin/hats/reviewer.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,14 @@ The Reviewer verifies that the Builder's implementation satisfies the Unit's Com
7575
- You MUST NOT approve if criteria are not met
7676
- You MUST NOT approve if configured testing requirements are not satisfied
7777
- **Validation**: Clear approve/reject with rationale
78-
- You MAY update ticket status in ticketing provider if configured (mark as "in review" or "done")
79-
- You MAY post completion summary to comms provider if configured (Slack/Teams notification)
78+
79+
#### Provider Sync — Review Outcome
80+
- If a `ticket` field exists in the reviewed unit's frontmatter:
81+
- **SHOULD** add the review outcome as a ticket comment (approved/rejected + summary)
82+
- If **approving**: update ticket to **Done**
83+
- If **rejecting**: keep ticket as **In Progress**, add rejection feedback as comment
84+
- **MAY** post a summary of the review outcome to the comms provider (if configured)
85+
- If MCP tools are unavailable, skip silently — never block review on provider sync
8086

8187
## Success Criteria
8288

plugin/hooks/inject-context.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,17 @@ if [ -z "$ITERATION_JSON" ]; then
211211

212212
echo "**To resume:** \`/resume <slug>\` or \`/resume\` if only one"
213213
echo ""
214+
# Inject provider context for pre-elaboration awareness
215+
CONFIG_LIB="${CLAUDE_PLUGIN_ROOT}/lib/config.sh"
216+
if [ -f "$CONFIG_LIB" ]; then
217+
# shellcheck source=/dev/null
218+
source "$CONFIG_LIB"
219+
PROVIDERS_MD=$(format_providers_markdown)
220+
if [ -n "$PROVIDERS_MD" ]; then
221+
echo "$PROVIDERS_MD"
222+
echo ""
223+
fi
224+
fi
214225
else
215226
# No AI-DLC state and no resumable intents - show available workflows for /elaborate
216227
if [ -n "$AVAILABLE_WORKFLOWS" ]; then

plugin/hooks/subagent-context.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,9 @@ echo ""
8989
CONFIG_LIB="${CLAUDE_PLUGIN_ROOT}/lib/config.sh"
9090
if [ -f "$CONFIG_LIB" ]; then
9191
# shellcheck source=/dev/null
92-
source "$CONFIG_LIB"
93-
PROVIDERS_MD=$(format_providers_markdown)
92+
source "$CONFIG_LIB" 2>/dev/null
93+
export_ai_dlc_config 2>/dev/null
94+
PROVIDERS_MD=$(format_providers_markdown 2>/dev/null)
9495
if [ -n "$PROVIDERS_MD" ]; then
9596
echo "$PROVIDERS_MD"
9697
echo ""

plugin/lib/config.sh

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,49 @@ _provider_mcp_hint() {
269269
esac
270270
}
271271

272+
# Load and merge provider instructions from three tiers
273+
# Usage: load_provider_instructions <category> <type> [inline_instructions]
274+
# Returns: Merged instruction text
275+
load_provider_instructions() {
276+
local category="$1" # ticketing, spec, design, comms
277+
local type="$2" # jira, notion, figma, slack, etc.
278+
local inline_instructions="$3" # from settings.yml, may be empty
279+
local merged=""
280+
281+
# Tier 1: Built-in default
282+
local builtin="${CLAUDE_PLUGIN_ROOT}/providers/${category}.md"
283+
if [[ -f "$builtin" ]]; then
284+
local body
285+
body=$(awk '/^---$/{n++; next} n>=2' "$builtin")
286+
merged="${body}"
287+
fi
288+
289+
# Tier 2: Inline instructions from settings.yml
290+
if [[ -n "$inline_instructions" ]]; then
291+
merged="${merged}
292+
293+
### Project-Specific Instructions (from settings.yml)
294+
${inline_instructions}"
295+
fi
296+
297+
# Tier 3: Project override from .ai-dlc/providers/{type}.md
298+
local repo_root
299+
repo_root=$(find_repo_root 2>/dev/null || echo "")
300+
if [[ -n "$repo_root" ]]; then
301+
local override="${repo_root}/.ai-dlc/providers/${type}.md"
302+
if [[ -f "$override" ]]; then
303+
local override_body
304+
override_body=$(awk '/^---$/{n++; next} n>=2' "$override")
305+
merged="${merged}
306+
307+
### Project Override (from .ai-dlc/providers/${type}.md)
308+
${override_body}"
309+
fi
310+
fi
311+
312+
printf '%s' "$merged"
313+
}
314+
272315
# Detect VCS hosting platform from git remote
273316
# Usage: detect_vcs_hosting [directory]
274317
# Returns: github | gitlab | bitbucket | ''
@@ -310,7 +353,7 @@ detect_ci_cd() {
310353
# Returns: JSON object with all provider categories
311354
load_providers() {
312355
local repo_root="${1:-$(find_repo_root)}"
313-
local result='{"specProvider":null,"ticketingProvider":null,"designProvider":null,"commsProvider":null,"vcsHosting":null,"ciCd":null}'
356+
local result='{"spec":null,"ticketing":null,"design":null,"comms":null,"vcsHosting":null,"ciCd":null}'
314357

315358
# Source 1: Declared providers from settings.yml
316359
if [ -n "$repo_root" ]; then
@@ -320,7 +363,7 @@ load_providers() {
320363
local providers
321364
providers=$(echo "$settings" | jq -c '.providers // {}')
322365
if [ "$providers" != "{}" ] && [ "$providers" != "null" ]; then
323-
for key in specProvider ticketingProvider designProvider commsProvider; do
366+
for key in spec ticketing design comms; do
324367
local val
325368
val=$(echo "$providers" | jq -c ".$key // null")
326369
if [ "$val" != "null" ]; then
@@ -335,7 +378,7 @@ load_providers() {
335378
local cached
336379
cached=$(han keep load providers.json --quiet 2>/dev/null || echo "")
337380
if [ -n "$cached" ] && [ "$cached" != "null" ]; then
338-
for key in specProvider ticketingProvider designProvider commsProvider; do
381+
for key in spec ticketing design comms; do
339382
local current
340383
current=$(echo "$result" | jq -c ".$key")
341384
if [ "$current" = "null" ]; then
@@ -373,7 +416,7 @@ format_providers_markdown() {
373416

374417
# Check if anything is configured
375418
local has_any=false
376-
for key in specProvider ticketingProvider designProvider commsProvider vcsHosting ciCd; do
419+
for key in spec ticketing design comms vcsHosting ciCd; do
377420
local val
378421
val=$(echo "$providers" | jq -r ".$key // empty")
379422
if [ -n "$val" ] && [ "$val" != "null" ]; then
@@ -385,7 +428,7 @@ format_providers_markdown() {
385428
if [ "$has_any" = "false" ]; then
386429
echo "### Project Providers"
387430
echo ""
388-
echo "No providers configured. Use \`ToolSearch\` to discover available MCP tools."
431+
echo "No providers configured. Use \`ToolSearch\` to discover available MCP tools, or configure providers in \`.ai-dlc/settings.yml\`."
389432
return
390433
fi
391434

@@ -413,7 +456,7 @@ format_providers_markdown() {
413456
fi
414457

415458
# Declared providers
416-
local categories="specProvider:Spec ticketingProvider:Ticketing designProvider:Design commsProvider:Comms"
459+
local categories="spec:Spec ticketing:Ticketing design:Design comms:Comms"
417460
for entry in $categories; do
418461
local key="${entry%%:*}"
419462
local label="${entry##*:}"
@@ -430,4 +473,37 @@ format_providers_markdown() {
430473

431474
echo ""
432475
echo "> **Tip:** Configure providers in \`.ai-dlc/settings.yml\` under \`providers:\` to enable automatic ticket sync and spec references."
476+
477+
# Provider Instructions section - merged from three tiers
478+
local has_instructions=false
479+
local category_map="ticketing:ticketing:Ticketing spec:spec:Spec design:design:Design comms:comms:Comms"
480+
local instructions_output=""
481+
482+
for entry in $category_map; do
483+
local key="${entry%%:*}"
484+
local rest="${entry#*:}"
485+
local category="${rest%%:*}"
486+
local label="${rest##*:}"
487+
local ptype
488+
ptype=$(echo "$providers" | jq -r ".$key.type // empty")
489+
if [ -n "$ptype" ]; then
490+
local inline
491+
inline=$(echo "$providers" | jq -r ".$key.instructions // empty")
492+
local merged
493+
merged=$(load_provider_instructions "$category" "$ptype" "$inline")
494+
if [ -n "$merged" ]; then
495+
has_instructions=true
496+
instructions_output="${instructions_output}
497+
#### ${label} (${ptype})
498+
${merged}
499+
"
500+
fi
501+
fi
502+
done
503+
504+
if [ "$has_instructions" = "true" ]; then
505+
echo ""
506+
echo "### Provider Instructions"
507+
printf '%s' "$instructions_output"
508+
fi
433509
}

0 commit comments

Comments
 (0)