specweave 1.0.256 → 1.0.259
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +56 -221
- package/README.md +31 -0
- package/bin/specweave.js +17 -0
- package/dist/src/adapters/README.md +4 -4
- package/dist/src/adapters/agents-md-generator.d.ts.map +1 -1
- package/dist/src/adapters/agents-md-generator.js +0 -2
- package/dist/src/adapters/agents-md-generator.js.map +1 -1
- package/dist/src/adapters/claude/README.md +3 -3
- package/dist/src/adapters/claude/adapter.js +3 -3
- package/dist/src/adapters/claude-md-generator.js +1 -1
- package/dist/src/adapters/claude-md-generator.js.map +1 -1
- package/dist/src/adapters/registry.yaml +1 -1
- package/dist/src/cli/commands/create-increment.d.ts +24 -0
- package/dist/src/cli/commands/create-increment.d.ts.map +1 -0
- package/dist/src/cli/commands/create-increment.js +53 -0
- package/dist/src/cli/commands/create-increment.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +48 -31
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/update.d.ts.map +1 -1
- package/dist/src/cli/commands/update.js +36 -0
- package/dist/src/cli/commands/update.js.map +1 -1
- package/dist/src/cli/helpers/init/directory-structure.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/directory-structure.js +13 -1
- package/dist/src/cli/helpers/init/directory-structure.js.map +1 -1
- package/dist/src/cli/helpers/init/summary-banner.d.ts +11 -0
- package/dist/src/cli/helpers/init/summary-banner.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/summary-banner.js +49 -3
- package/dist/src/cli/helpers/init/summary-banner.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +0 -1
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js +6 -2
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js.map +1 -1
- package/dist/src/core/ac-progress-sync.d.ts +13 -0
- package/dist/src/core/ac-progress-sync.d.ts.map +1 -1
- package/dist/src/core/ac-progress-sync.js +28 -0
- package/dist/src/core/ac-progress-sync.js.map +1 -1
- package/dist/src/core/config/types.d.ts +24 -1
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js +6 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/doctor/checkers/project-structure-checker.d.ts +1 -0
- package/dist/src/core/doctor/checkers/project-structure-checker.d.ts.map +1 -1
- package/dist/src/core/doctor/checkers/project-structure-checker.js +53 -3
- package/dist/src/core/doctor/checkers/project-structure-checker.js.map +1 -1
- package/dist/src/core/fabric/security-scanner.d.ts.map +1 -1
- package/dist/src/core/fabric/security-scanner.js +70 -9
- package/dist/src/core/fabric/security-scanner.js.map +1 -1
- package/dist/src/core/increment/increment-utils.d.ts +6 -0
- package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
- package/dist/src/core/increment/increment-utils.js +5 -0
- package/dist/src/core/increment/increment-utils.js.map +1 -1
- package/dist/src/core/living-docs/discovery.d.ts +2 -0
- package/dist/src/core/living-docs/discovery.d.ts.map +1 -1
- package/dist/src/core/living-docs/discovery.js +91 -17
- package/dist/src/core/living-docs/discovery.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts +5 -0
- package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/index.js +3 -3
- package/dist/src/core/living-docs/intelligent-analyzer/index.js.map +1 -1
- package/dist/src/core/living-docs/lsp-bootstrapper.d.ts +64 -0
- package/dist/src/core/living-docs/lsp-bootstrapper.d.ts.map +1 -0
- package/dist/src/core/living-docs/lsp-bootstrapper.js +118 -0
- package/dist/src/core/living-docs/lsp-bootstrapper.js.map +1 -0
- package/dist/src/core/project/project-service.d.ts +10 -1
- package/dist/src/core/project/project-service.d.ts.map +1 -1
- package/dist/src/core/project/project-service.js +37 -2
- package/dist/src/core/project/project-service.js.map +1 -1
- package/dist/src/core/universal-auto-create.d.ts +64 -0
- package/dist/src/core/universal-auto-create.d.ts.map +1 -0
- package/dist/src/core/universal-auto-create.js +228 -0
- package/dist/src/core/universal-auto-create.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/PLUGIN.md +0 -3
- package/plugins/specweave/commands/living-docs.md +0 -2
- package/plugins/specweave/hooks/stop-sync.sh +34 -5
- package/plugins/specweave/hooks/user-prompt-submit.sh +115 -326
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +19 -5
- package/plugins/specweave/hooks/v2/handlers/ac-sync-dispatcher.sh +14 -4
- package/plugins/specweave/hooks/v2/handlers/universal-auto-create-dispatcher.sh +181 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.js +4 -2
- package/plugins/specweave/scripts/skill-context.sh +160 -0
- package/plugins/specweave/skills/architect/SKILL.md +1 -1
- package/plugins/specweave/skills/archive-increments/SKILL.md +13 -3
- package/plugins/specweave/skills/auto/SKILL.md +92 -1038
- package/plugins/specweave/skills/do/SKILL.md +66 -1106
- package/plugins/specweave/skills/docs/SKILL.md +124 -56
- package/plugins/specweave/skills/done/SKILL.md +76 -1406
- package/plugins/specweave/skills/framework/SKILL.md +1 -1
- package/plugins/specweave/skills/increment/SKILL.md +1 -1
- package/plugins/specweave/skills/increment-planner/SKILL.md +29 -19
- package/plugins/specweave/skills/jobs/SKILL.md +52 -0
- package/plugins/specweave/skills/multi-project-spec-mapper/SKILL.md +1 -1
- package/plugins/specweave/skills/save/SKILL.md +51 -1372
- package/plugins/specweave/skills/smart-reopen-detector/SKILL.md +1 -1
- package/plugins/specweave/skills/tdd-orchestrator/SKILL.md +1 -1
- package/plugins/specweave/skills/validate/SKILL.md +65 -848
- package/plugins/specweave-backend/skills/database-optimizer/SKILL.md +1 -1
- package/plugins/specweave-backend/skills/graphql/SKILL.md +1 -1
- package/plugins/specweave-frontend/skills/design-system-architect/SKILL.md +1 -1
- package/plugins/specweave-frontend/skills/frontend/SKILL.md +1 -1
- package/plugins/specweave-frontend/skills/frontend-architect/SKILL.md +1 -1
- package/plugins/specweave-frontend/skills/frontend-design/SKILL.md +1 -1
- package/plugins/specweave-frontend/skills/i18n-expert/SKILL.md +1 -1
- package/plugins/specweave-payments/skills/billing-automation/SKILL.md +1 -1
- package/plugins/specweave-testing/skills/accessibility-testing/SKILL.md +1 -1
- package/src/templates/CLAUDE.md.template +50 -356
- package/src/templates/config.json.template +5 -1
- package/plugins/specweave/commands/brownfield-analyzer.md +0 -408
- package/plugins/specweave/commands/brownfield-onboarder.md +0 -837
- package/plugins/specweave/commands/export-skills.md +0 -179
|
@@ -373,8 +373,8 @@ escape_json_early() {
|
|
|
373
373
|
|
|
374
374
|
# v1.0.254: Prompt safety limits to prevent "Prompt is too long" errors
|
|
375
375
|
# These must match the constants in src/core/lazy-loading/llm-plugin-detector.ts
|
|
376
|
-
MAX_ADDITIONAL_CONTEXT_LENGTH=
|
|
377
|
-
MAX_SKILL_FIRST_PROMPT_LENGTH=
|
|
376
|
+
MAX_ADDITIONAL_CONTEXT_LENGTH=3000
|
|
377
|
+
MAX_SKILL_FIRST_PROMPT_LENGTH=800
|
|
378
378
|
|
|
379
379
|
# Helper: Output approve response with context (Claude Code hook format v1.0.166)
|
|
380
380
|
# CRITICAL: systemMessage is NOT a valid field for UserPromptSubmit hooks!
|
|
@@ -525,17 +525,7 @@ if [[ -f "$LSP_STATE_FILE" ]] && command -v jq >/dev/null 2>&1; then
|
|
|
525
525
|
MISSING_SERVERS=$(jq -r '.missing[] | "- **\(.language)**: `\(.install)`"' "$LSP_STATE_FILE" 2>/dev/null)
|
|
526
526
|
|
|
527
527
|
if [[ -n "$MISSING_SERVERS" ]]; then
|
|
528
|
-
LSP_WARNING_MSG="
|
|
529
|
-
|
|
530
|
-
The following language servers are not installed:
|
|
531
|
-
$MISSING_SERVERS
|
|
532
|
-
|
|
533
|
-
LSP provides semantic code understanding (findReferences, goToDefinition, diagnostics).
|
|
534
|
-
Without it, Claude uses text search which is slower and less accurate.
|
|
535
|
-
|
|
536
|
-
📖 Guide: https://spec-weave.com/docs/guides/lsp-integration
|
|
537
|
-
|
|
538
|
-
---
|
|
528
|
+
LSP_WARNING_MSG="LSP missing: ${MISSING_SERVERS}. Install for semantic code intelligence. Guide: https://spec-weave.com/docs/guides/lsp-integration
|
|
539
529
|
|
|
540
530
|
"
|
|
541
531
|
# Mark as warned so we don't show again this session
|
|
@@ -1370,57 +1360,12 @@ Task({
|
|
|
1370
1360
|
# ask targeted questions first. If complete, proceed directly.
|
|
1371
1361
|
DEEP_INTERVIEW_MSG=""
|
|
1372
1362
|
if [[ "$DEEP_INTERVIEW_ENABLED" == "true" ]]; then
|
|
1373
|
-
DEEP_INTERVIEW_MSG="
|
|
1374
|
-
|
|
1375
|
-
🧠 **SMART INTERVIEW GATE** (Deep Interview Mode active)
|
|
1376
|
-
|
|
1377
|
-
BEFORE calling sw:increment-planner, assess this prompt for completeness.
|
|
1378
|
-
Consider ALL prior messages in this conversation.
|
|
1379
|
-
|
|
1380
|
-
**Assess complexity:**
|
|
1381
|
-
- Trivial → need almost nothing, call increment-planner now
|
|
1382
|
-
- Small (single component) → need: tech stack + basic flow
|
|
1383
|
-
- Medium (multiple components) → need: stack + integrations + user flows + auth
|
|
1384
|
-
- Large (platform/multi-service) → need: architecture + security + deployment + edge cases
|
|
1385
|
-
|
|
1386
|
-
**Check signals (weight by project type):**
|
|
1387
|
-
- Technical: stack, frameworks, DB, auth, API integrations, deployment target
|
|
1388
|
-
- Product: target users, core flows, business model, MVP scope
|
|
1389
|
-
- Operational: env vars/keys, CI/CD, monitoring
|
|
1390
|
-
|
|
1391
|
-
**Decision:**
|
|
1392
|
-
- Sufficient detail → call increment-planner immediately with full context
|
|
1393
|
-
- Gaps detected → ask 2-5 targeted questions about ONLY what is missing, then call increment-planner after answers received
|
|
1394
|
-
- NEVER ask 10+ questions. NEVER repeat what the user already said."
|
|
1363
|
+
DEEP_INTERVIEW_MSG=" Assess prompt completeness first — if gaps exist, ask 2-5 targeted questions before calling."
|
|
1395
1364
|
fi
|
|
1396
1365
|
|
|
1397
|
-
MSG="${WIP_WARNING}${AUTOLOAD_PREFIX}
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
**Your FIRST tool call must be:**
|
|
1402
|
-
\`\`\`
|
|
1403
|
-
Skill({ skill: \"sw:increment-planner\", args: \"${ESCAPED_PROMPT}\" })
|
|
1404
|
-
\`\`\`
|
|
1405
|
-
|
|
1406
|
-
**Order matters:**
|
|
1407
|
-
1. ✅ Call Skill tool FIRST (as shown above)
|
|
1408
|
-
2. ✅ THEN proceed with implementation normally
|
|
1409
|
-
|
|
1410
|
-
**Detection**: Feature request (confidence: ${INC_CONF})
|
|
1411
|
-
**Reason**: ${INC_REASON}${AGENT_DIRECTIVE}${DEEP_INTERVIEW_MSG}
|
|
1412
|
-
|
|
1413
|
-
---
|
|
1414
|
-
|
|
1415
|
-
⚠️ **SKILL CHAINING REQUIRED** - \"SKILL FIRST\" does NOT mean \"only one skill\"!
|
|
1416
|
-
|
|
1417
|
-
After sw:increment-planner, ALSO invoke domain skills for your tech stack:
|
|
1418
|
-
- React/Vue/Angular → \`sw-frontend:frontend-architect\`
|
|
1419
|
-
- .NET/C# → \`sw-backend:dotnet-backend\`
|
|
1420
|
-
- Stripe → \`sw-payments:stripe-integration\`
|
|
1421
|
-
- After code → LSP works automatically (use findReferences, goToDefinition)
|
|
1422
|
-
|
|
1423
|
-
See CLAUDE.md section \"MANDATORY: Skill Chaining\" for full pattern."
|
|
1366
|
+
MSG="${WIP_WARNING}${AUTOLOAD_PREFIX}SKILL FIRST: \`Skill({ skill: \"sw:increment-planner\", args: \"${ESCAPED_PROMPT}\" })\` — call BEFORE implementation.
|
|
1367
|
+
Detection: ${INC_REASON} (confidence: ${INC_CONF}).${AGENT_DIRECTIVE}${DEEP_INTERVIEW_MSG}
|
|
1368
|
+
After increment-planner, chain domain skills per tech stack (see CLAUDE.md Skill Chaining)."
|
|
1424
1369
|
# Use approve+additionalContext so Claude can read and follow
|
|
1425
1370
|
# the SKILL FIRST instructions (block erases prompt from context)
|
|
1426
1371
|
output_approve_with_context "$MSG"
|
|
@@ -1428,20 +1373,7 @@ See CLAUDE.md section \"MANDATORY: Skill Chaining\" for full pattern."
|
|
|
1428
1373
|
else
|
|
1429
1374
|
# v1.0.169: Also suggest direct skill call for non-mandatory
|
|
1430
1375
|
ESCAPED_PROMPT_SUGGEST=$(truncate_and_escape_prompt "$PROMPT")
|
|
1431
|
-
MSG="${WIP_WARNING}${AUTOLOAD_PREFIX}
|
|
1432
|
-
|
|
1433
|
-
Consider creating an increment first:
|
|
1434
|
-
\`\`\`
|
|
1435
|
-
Skill({ skill: \"sw:increment-planner\", args: \"${ESCAPED_PROMPT_SUGGEST}\" })
|
|
1436
|
-
\`\`\`
|
|
1437
|
-
|
|
1438
|
-
Or via command: \`$CMD\`
|
|
1439
|
-
|
|
1440
|
-
*Reason: $INC_REASON*${AGENT_DIRECTIVE}
|
|
1441
|
-
|
|
1442
|
-
---
|
|
1443
|
-
|
|
1444
|
-
*Tip: Disable with \`incrementAssist.enabled: false\` in config.json*"
|
|
1376
|
+
MSG="${WIP_WARNING}${AUTOLOAD_PREFIX}Increment suggested: \`Skill({ skill: \"sw:increment-planner\", args: \"${ESCAPED_PROMPT_SUGGEST}\" })\` or \`$CMD\`. Reason: $INC_REASON${AGENT_DIRECTIVE}"
|
|
1445
1377
|
output_approve_with_context "$MSG"
|
|
1446
1378
|
exit 0
|
|
1447
1379
|
fi
|
|
@@ -1450,20 +1382,7 @@ Or via command: \`$CMD\`
|
|
|
1450
1382
|
hotfix)
|
|
1451
1383
|
# v1.0.169: Direct skill call for hotfix too
|
|
1452
1384
|
ESCAPED_PROMPT_HOTFIX=$(truncate_and_escape_prompt "$PROMPT")
|
|
1453
|
-
MSG="${WIP_WARNING}${AUTOLOAD_PREFIX}
|
|
1454
|
-
|
|
1455
|
-
Create a hotfix increment:
|
|
1456
|
-
\`\`\`
|
|
1457
|
-
Skill({ skill: \"sw:increment-planner\", args: \"--type=hotfix ${ESCAPED_PROMPT_HOTFIX}\" })
|
|
1458
|
-
\`\`\`
|
|
1459
|
-
|
|
1460
|
-
Or via command: \`/sw:increment --type=hotfix \"${INC_NAME:-urgent-fix}\"\`
|
|
1461
|
-
|
|
1462
|
-
*Reason: $INC_REASON*
|
|
1463
|
-
|
|
1464
|
-
---
|
|
1465
|
-
|
|
1466
|
-
*Tip: Disable with \`incrementAssist.enabled: false\` in config.json*"
|
|
1385
|
+
MSG="${WIP_WARNING}${AUTOLOAD_PREFIX}Hotfix detected: \`Skill({ skill: \"sw:increment-planner\", args: \"--type=hotfix ${ESCAPED_PROMPT_HOTFIX}\" })\`. Reason: $INC_REASON"
|
|
1467
1386
|
output_approve_with_context "$MSG"
|
|
1468
1387
|
exit 0
|
|
1469
1388
|
;;
|
|
@@ -1471,19 +1390,7 @@ Or via command: \`/sw:increment --type=hotfix \"${INC_NAME:-urgent-fix}\"\`
|
|
|
1471
1390
|
reopen)
|
|
1472
1391
|
HINT=""
|
|
1473
1392
|
[[ -n "$INC_KEYWORD" ]] && HINT=" (look for: *$INC_KEYWORD*)"
|
|
1474
|
-
MSG="${AUTOLOAD_PREFIX}
|
|
1475
|
-
|
|
1476
|
-
Consider reopening the existing increment:
|
|
1477
|
-
\`\`\`
|
|
1478
|
-
/sw:status # Find the related increment
|
|
1479
|
-
specweave resume <id> # Reopen it
|
|
1480
|
-
\`\`\`
|
|
1481
|
-
|
|
1482
|
-
*Reason: $INC_REASON*
|
|
1483
|
-
|
|
1484
|
-
---
|
|
1485
|
-
|
|
1486
|
-
*Tip: Disable with \`incrementAssist.enabled: false\` in config.json*"
|
|
1393
|
+
MSG="${AUTOLOAD_PREFIX}Related to previous work$HINT. Consider: \`/sw:status\` then \`specweave resume <id>\`. Reason: $INC_REASON"
|
|
1487
1394
|
output_approve_with_context "$MSG"
|
|
1488
1395
|
exit 0
|
|
1489
1396
|
;;
|
|
@@ -1495,20 +1402,7 @@ specweave resume <id> # Reopen it
|
|
|
1495
1402
|
CMD_SMALLFIX="/sw:increment"
|
|
1496
1403
|
[[ -n "$INC_NAME" ]] && CMD_SMALLFIX="/sw:increment \"$INC_NAME\""
|
|
1497
1404
|
|
|
1498
|
-
MSG="${WIP_WARNING}${AUTOLOAD_PREFIX}
|
|
1499
|
-
|
|
1500
|
-
Consider creating an increment:
|
|
1501
|
-
\`\`\`
|
|
1502
|
-
Skill({ skill: \"sw:increment-planner\", args: \"${ESCAPED_PROMPT_SMALLFIX}\" })
|
|
1503
|
-
\`\`\`
|
|
1504
|
-
|
|
1505
|
-
Or via command: \`$CMD_SMALLFIX\`
|
|
1506
|
-
|
|
1507
|
-
*Reason: $INC_REASON*${AGENT_DIRECTIVE}
|
|
1508
|
-
|
|
1509
|
-
---
|
|
1510
|
-
|
|
1511
|
-
*Tip: Disable with \`incrementAssist.enabled: false\` in config.json*"
|
|
1405
|
+
MSG="${WIP_WARNING}${AUTOLOAD_PREFIX}Small change — consider tracking: \`Skill({ skill: \"sw:increment-planner\", args: \"${ESCAPED_PROMPT_SMALLFIX}\" })\` or \`$CMD_SMALLFIX\`. Reason: $INC_REASON${AGENT_DIRECTIVE}"
|
|
1512
1406
|
output_approve_with_context "$MSG"
|
|
1513
1407
|
exit 0
|
|
1514
1408
|
;;
|
|
@@ -1527,37 +1421,11 @@ Or via command: \`$CMD_SMALLFIX\`
|
|
|
1527
1421
|
[[ -n "$LSP_EXPLICIT_REQUEST_MSG" ]] && SKILL_ONLY_PREFIX="${SKILL_ONLY_PREFIX}${LSP_EXPLICIT_REQUEST_MSG}"
|
|
1528
1422
|
|
|
1529
1423
|
if [[ "$SKILL_MANDATORY" == "true" ]]; then
|
|
1530
|
-
MSG="${SKILL_ONLY_PREFIX}
|
|
1531
|
-
║ 🎯 SKILL REQUIRED - This task needs specialized skill support ║
|
|
1532
|
-
╚══════════════════════════════════════════════════════════════════════════════╝
|
|
1533
|
-
|
|
1534
|
-
<skill_invocation_required>
|
|
1535
|
-
### 🎯 MANDATORY: Use ${SKILL_INVOCATION} Skill
|
|
1536
|
-
|
|
1537
|
-
You MUST use this skill for this task. Do NOT proceed without loading it first.
|
|
1538
|
-
|
|
1539
|
-
**Invoke NOW using Skill tool:**
|
|
1540
|
-
\`\`\`typescript
|
|
1541
|
-
Skill({ skill: \"${SKILL_INVOCATION}\" })
|
|
1542
|
-
\`\`\`
|
|
1543
|
-
|
|
1544
|
-
**Why this skill is required:**
|
|
1545
|
-
${SKILL_REASON:-This skill provides specialized support for your task.}
|
|
1546
|
-
|
|
1547
|
-
⚠️ **Do NOT skip this** - the skill has domain expertise needed for this operation.
|
|
1548
|
-
</skill_invocation_required>"
|
|
1424
|
+
MSG="${SKILL_ONLY_PREFIX}SKILL REQUIRED: \`Skill({ skill: \"${SKILL_INVOCATION}\" })\` — call before proceeding. ${SKILL_REASON:-Specialized support needed.}"
|
|
1549
1425
|
output_approve_with_context "$MSG"
|
|
1550
1426
|
exit 0
|
|
1551
1427
|
else
|
|
1552
|
-
|
|
1553
|
-
MSG="${SKILL_ONLY_PREFIX}💡 **Skill Recommended**: Consider using a specialized skill.
|
|
1554
|
-
|
|
1555
|
-
Use \`${SKILL_INVOCATION}\` for better results:
|
|
1556
|
-
\`\`\`typescript
|
|
1557
|
-
Skill({ skill: \"${SKILL_INVOCATION}\" })
|
|
1558
|
-
\`\`\`
|
|
1559
|
-
|
|
1560
|
-
*${SKILL_REASON:-This skill provides specialized support for your task.}*"
|
|
1428
|
+
MSG="${SKILL_ONLY_PREFIX}Skill recommended: \`Skill({ skill: \"${SKILL_INVOCATION}\" })\`. ${SKILL_REASON:-Specialized support for this task.}"
|
|
1561
1429
|
output_approve_with_context "$MSG"
|
|
1562
1430
|
exit 0
|
|
1563
1431
|
fi
|
|
@@ -1595,126 +1463,29 @@ Skill({ skill: \"${SKILL_INVOCATION}\" })
|
|
|
1595
1463
|
if [[ "$ROUTING_SKILLS_COUNT" -gt 0 || -n "$AUTOLOAD_PLUGINS_MSG" ]]; then
|
|
1596
1464
|
BRAIN_MSG=""
|
|
1597
1465
|
|
|
1598
|
-
#
|
|
1599
|
-
BRAIN_MSG
|
|
1466
|
+
# Compact router output — one line per decision
|
|
1467
|
+
[[ -n "$PLUGINS_INSTALLED" ]] && BRAIN_MSG+="Plugins loaded: ${PLUGINS_INSTALLED}. "
|
|
1468
|
+
[[ -n "$PLUGINS_ALREADY" ]] && BRAIN_MSG+="Plugins active: ${PLUGINS_ALREADY}. "
|
|
1600
1469
|
|
|
1601
|
-
# Analysis summary table
|
|
1602
|
-
BRAIN_MSG+="## Analysis\\n"
|
|
1603
|
-
BRAIN_MSG+="| Aspect | Decision |\\n"
|
|
1604
|
-
BRAIN_MSG+="|--------|----------|\\n"
|
|
1605
|
-
|
|
1606
|
-
# Plugins row
|
|
1607
|
-
if [[ -n "$PLUGINS_INSTALLED" ]]; then
|
|
1608
|
-
BRAIN_MSG+="| Plugins | ✅ Loaded: ${PLUGINS_INSTALLED} |\\n"
|
|
1609
|
-
elif [[ -n "$PLUGINS_ALREADY" ]]; then
|
|
1610
|
-
BRAIN_MSG+="| Plugins | ✅ Using: ${PLUGINS_ALREADY} |\\n"
|
|
1611
|
-
fi
|
|
1612
|
-
|
|
1613
|
-
# Increment row
|
|
1614
1470
|
if [[ "$INC_ACTION" == "new" || "$INC_ACTION" == "hotfix" ]]; then
|
|
1615
|
-
BRAIN_MSG+="
|
|
1471
|
+
BRAIN_MSG+="Increment: create \\\"${INC_NAME:-new-feature}\\\" (${INC_ACTION}). "
|
|
1616
1472
|
elif [[ "$INC_ACTION" == "reopen" ]]; then
|
|
1617
|
-
BRAIN_MSG+="
|
|
1473
|
+
BRAIN_MSG+="Increment: reopen existing"
|
|
1474
|
+
[[ -n "$INC_KEYWORD" ]] && BRAIN_MSG+=" (${INC_KEYWORD})"
|
|
1475
|
+
BRAIN_MSG+=". "
|
|
1618
1476
|
fi
|
|
1619
1477
|
|
|
1620
|
-
# Primary skill row
|
|
1621
1478
|
if [[ -n "$PRIMARY_SKILL" ]]; then
|
|
1622
|
-
|
|
1623
|
-
fi
|
|
1624
|
-
|
|
1625
|
-
# Secondary skills row
|
|
1626
|
-
if [[ -n "$SECONDARY_SKILLS" ]]; then
|
|
1627
|
-
BRAIN_MSG+="| Supporting | ${SECONDARY_SKILLS} |\\n"
|
|
1628
|
-
fi
|
|
1629
|
-
|
|
1630
|
-
BRAIN_MSG+="\\n"
|
|
1631
|
-
|
|
1632
|
-
# Workflow section
|
|
1633
|
-
BRAIN_MSG+="## Workflow\\n\\n"
|
|
1634
|
-
|
|
1635
|
-
STEP_NUM=1
|
|
1636
|
-
|
|
1637
|
-
# Step: Create increment (if needed)
|
|
1638
|
-
if [[ "$INC_ACTION" == "new" ]]; then
|
|
1639
|
-
CMD="/sw:increment"
|
|
1640
|
-
[[ -n "$INC_NAME" ]] && CMD="/sw:increment \\\"$INC_NAME\\\""
|
|
1641
|
-
BRAIN_MSG+="### Step ${STEP_NUM}: Create Increment\\n"
|
|
1642
|
-
BRAIN_MSG+="\\\`\\\`\\\`\\n${CMD}\\n\\\`\\\`\\\`\\n"
|
|
1643
|
-
BRAIN_MSG+="*${INC_REASON:-Tracks this feature work with specs}*\\n\\n"
|
|
1644
|
-
STEP_NUM=$((STEP_NUM + 1))
|
|
1645
|
-
elif [[ "$INC_ACTION" == "hotfix" ]]; then
|
|
1646
|
-
CMD="/sw:increment --type=hotfix \\\"${INC_NAME:-urgent-fix}\\\""
|
|
1647
|
-
BRAIN_MSG+="### Step ${STEP_NUM}: Create Hotfix Increment\\n"
|
|
1648
|
-
BRAIN_MSG+="\\\`\\\`\\\`\\n${CMD}\\n\\\`\\\`\\\`\\n"
|
|
1649
|
-
BRAIN_MSG+="*${INC_REASON:-Urgent production issue}*\\n\\n"
|
|
1650
|
-
STEP_NUM=$((STEP_NUM + 1))
|
|
1651
|
-
elif [[ "$INC_ACTION" == "reopen" ]]; then
|
|
1652
|
-
BRAIN_MSG+="### Step ${STEP_NUM}: Find & Reopen Increment\\n"
|
|
1653
|
-
BRAIN_MSG+="\\\`\\\`\\\`\\n/sw:status # Find related increment\\nspecweave resume <id>\\n\\\`\\\`\\\`\\n"
|
|
1654
|
-
[[ -n "$INC_KEYWORD" ]] && BRAIN_MSG+="*Look for: ${INC_KEYWORD}*\\n"
|
|
1655
|
-
BRAIN_MSG+="\\n"
|
|
1656
|
-
STEP_NUM=$((STEP_NUM + 1))
|
|
1657
|
-
fi
|
|
1658
|
-
|
|
1659
|
-
# Step: SPAWN AGENTS (v1.0.155 - Task tool directive)
|
|
1660
|
-
if [[ -n "$PRIMARY_SKILL" ]]; then
|
|
1661
|
-
BRAIN_MSG+="### Step ${STEP_NUM}: 🚀 SPAWN SPECIALIZED AGENTS\\n\\n"
|
|
1662
|
-
|
|
1663
|
-
# Build agent subagent_type from skill info
|
|
1664
|
-
# Format: plugin:skill:skill (e.g., sw-frontend:frontend-architect:frontend-architect)
|
|
1479
|
+
# Extract agent type for Task tool
|
|
1665
1480
|
PRIMARY_PLUGIN=$(echo "$JSON_OUTPUT" | jq -r '.routing.skills[] | select(.priority == "primary") | .plugin // empty' 2>/dev/null | head -1)
|
|
1666
1481
|
PRIMARY_SKILL_NAME=$(echo "$JSON_OUTPUT" | jq -r '.routing.skills[] | select(.priority == "primary") | .name // empty' 2>/dev/null | head -1)
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
BRAIN_MSG+="**⚠️ MANDATORY: Use Task tool to spawn agent for implementation**\\n\\n"
|
|
1672
|
-
BRAIN_MSG+="\\\`\\\`\\\`typescript\\n"
|
|
1673
|
-
BRAIN_MSG+="Task({\\n"
|
|
1674
|
-
BRAIN_MSG+=" subagent_type: \\\"${AGENT_TYPE}\\\",\\n"
|
|
1675
|
-
BRAIN_MSG+=" prompt: \\\"Implement [describe task]...\\\",\\n"
|
|
1676
|
-
BRAIN_MSG+=" description: \\\"[short description]\\\"\\n"
|
|
1677
|
-
BRAIN_MSG+="})\\n"
|
|
1678
|
-
BRAIN_MSG+="\\\`\\\`\\\`\\n\\n"
|
|
1679
|
-
|
|
1680
|
-
BRAIN_MSG+="**Why**: Specialized agents have deep domain knowledge and produce better code than direct implementation.\\n\\n"
|
|
1681
|
-
[[ -n "$PRIMARY_REASON" ]] && BRAIN_MSG+="**Agent expertise**: *${PRIMARY_REASON}*\\n\\n"
|
|
1682
|
-
fi
|
|
1683
|
-
|
|
1684
|
-
# Add secondary agents if present
|
|
1685
|
-
if [[ -n "$SECONDARY_SKILLS" ]]; then
|
|
1686
|
-
BRAIN_MSG+="**Additional agents available**:\\n"
|
|
1687
|
-
# Parse each secondary skill
|
|
1688
|
-
echo "$JSON_OUTPUT" | jq -r '.routing.skills[] | select(.priority == "secondary") | "\(.plugin):\(.name):\(.name)"' 2>/dev/null | while read -r sec_agent; do
|
|
1689
|
-
[[ -n "$sec_agent" ]] && BRAIN_MSG+="- \`${sec_agent}\`\\n"
|
|
1690
|
-
done
|
|
1691
|
-
BRAIN_MSG+="\\n"
|
|
1692
|
-
fi
|
|
1693
|
-
|
|
1694
|
-
# Add invoke timing hint
|
|
1695
|
-
case "$PRIMARY_INVOKE" in
|
|
1696
|
-
immediate)
|
|
1697
|
-
BRAIN_MSG+="**Timing**: Spawn agent NOW - task is self-contained\\n\\n"
|
|
1698
|
-
;;
|
|
1699
|
-
after_increment)
|
|
1700
|
-
BRAIN_MSG+="**Timing**: Spawn agent AFTER creating increment\\n\\n"
|
|
1701
|
-
;;
|
|
1702
|
-
after_planning)
|
|
1703
|
-
BRAIN_MSG+="**Timing**: Enter plan mode first, THEN spawn agent\\n\\n"
|
|
1704
|
-
;;
|
|
1705
|
-
esac
|
|
1706
|
-
|
|
1707
|
-
STEP_NUM=$((STEP_NUM + 1))
|
|
1708
|
-
fi
|
|
1709
|
-
|
|
1710
|
-
# Add plan mode suggestion if recommended
|
|
1711
|
-
if [[ "$SUGGEST_PLAN" == "true" ]]; then
|
|
1712
|
-
BRAIN_MSG+="### 💡 Suggestion: Use Plan Mode\\n"
|
|
1713
|
-
BRAIN_MSG+="This task appears complex. Consider entering plan mode first.\\n\\n"
|
|
1482
|
+
BRAIN_MSG+="Primary skill: ${PRIMARY_SKILL}"
|
|
1483
|
+
[[ -n "$PRIMARY_PLUGIN" && -n "$PRIMARY_SKILL_NAME" ]] && BRAIN_MSG+=" (agent: ${PRIMARY_PLUGIN}:${PRIMARY_SKILL_NAME}:${PRIMARY_SKILL_NAME})"
|
|
1484
|
+
BRAIN_MSG+=", invoke: ${PRIMARY_INVOKE:-after_increment}. "
|
|
1485
|
+
[[ -n "$SECONDARY_SKILLS" ]] && BRAIN_MSG+="Also: ${SECONDARY_SKILLS}. "
|
|
1714
1486
|
fi
|
|
1715
1487
|
|
|
1716
|
-
|
|
1717
|
-
BRAIN_MSG+="---\\n*Router Brain v1.0.150*"
|
|
1488
|
+
[[ "$SUGGEST_PLAN" == "true" ]] && BRAIN_MSG+="Suggest plan mode. "
|
|
1718
1489
|
|
|
1719
1490
|
output_approve_with_context "$BRAIN_MSG"
|
|
1720
1491
|
exit 0
|
|
@@ -1737,14 +1508,34 @@ Skill({ skill: \"${SKILL_INVOCATION}\" })
|
|
|
1737
1508
|
fi
|
|
1738
1509
|
|
|
1739
1510
|
# ==================================================================
|
|
1740
|
-
# KEYWORD FALLBACK
|
|
1511
|
+
# KEYWORD FALLBACK FOR INCREMENT DISCIPLINE (v1.0.257)
|
|
1741
1512
|
# ==================================================================
|
|
1742
|
-
#
|
|
1743
|
-
#
|
|
1513
|
+
# Plugin keyword fallback was removed in v1.0.159 (too aggressive for
|
|
1514
|
+
# auto-installing plugins). But INCREMENT DISCIPLINE still needs a
|
|
1515
|
+
# fallback when LLM detection fails/times out. Without this, prompts
|
|
1516
|
+
# like "big test react component" silently bypass spec-first discipline.
|
|
1744
1517
|
#
|
|
1745
|
-
#
|
|
1746
|
-
|
|
1747
|
-
|
|
1518
|
+
# This fallback ONLY handles increment suggestions (not plugin installs).
|
|
1519
|
+
if [[ "$LLM_DETECTION_FAILED" == "true" && "$INCREMENT_ASSIST_ENABLED" == "true" ]]; then
|
|
1520
|
+
# Check for implementation-intent keywords
|
|
1521
|
+
if echo "$PROMPT" | grep -qiE "(test|component|feature|fix|refactor|setup|configure|integrate|migrate|upgrade|write|style|design|add|create|implement|build|develop|deploy|scaffold|generate)"; then
|
|
1522
|
+
# Exclude questions (starting with question words or ending with ?)
|
|
1523
|
+
if ! echo "$PROMPT" | grep -qiE "^[[:space:]]*(what|how|why|explain|tell me|can you|does|should|is there|where|when|which)" && \
|
|
1524
|
+
! echo "$PROMPT" | grep -qE "\?[[:space:]]*$"; then
|
|
1525
|
+
FALLBACK_ESCAPED=$(truncate_and_escape_prompt "$PROMPT")
|
|
1526
|
+
if [[ "$INCREMENT_MANDATORY_CONFIG" == "true" ]]; then
|
|
1527
|
+
FALLBACK_MSG="SKILL FIRST: \`Skill({ skill: \"sw:increment-planner\", args: \"${FALLBACK_ESCAPED}\" })\` — call BEFORE implementation.
|
|
1528
|
+
Detection: Implementation keywords detected (LLM unavailable, keyword fallback).
|
|
1529
|
+
After increment-planner, chain domain skills per tech stack (see CLAUDE.md Skill Chaining)."
|
|
1530
|
+
else
|
|
1531
|
+
FALLBACK_MSG="Increment suggested: \`Skill({ skill: \"sw:increment-planner\", args: \"${FALLBACK_ESCAPED}\" })\`. Reason: Implementation keywords detected (LLM unavailable, keyword fallback)."
|
|
1532
|
+
fi
|
|
1533
|
+
echo "[$(date -Iseconds)] keyword-fallback | prompt_keywords_matched=true | mandatory=$INCREMENT_MANDATORY_CONFIG" >> "$LAZY_LOAD_LOG"
|
|
1534
|
+
output_approve_with_context "$FALLBACK_MSG"
|
|
1535
|
+
exit 0
|
|
1536
|
+
fi
|
|
1537
|
+
fi
|
|
1538
|
+
fi
|
|
1748
1539
|
fi
|
|
1749
1540
|
fi
|
|
1750
1541
|
fi
|
|
@@ -1823,35 +1614,7 @@ if [[ -n "$SW_PROJECT_ROOT" ]] && [[ -d "$SW_PROJECT_ROOT/.specweave" ]]; then
|
|
|
1823
1614
|
|
|
1824
1615
|
# v1.0.160: STRICT TDD adds mandatory blocking directive
|
|
1825
1616
|
if [[ "$TDD_ENFORCEMENT" == "strict" ]]; then
|
|
1826
|
-
TDD_MSG="
|
|
1827
|
-
|
|
1828
|
-
⚠️ **YOU MUST FOLLOW RED→GREEN→REFACTOR OR YOUR CHANGES WILL BE REJECTED**
|
|
1829
|
-
|
|
1830
|
-
**MANDATORY WORKFLOW (NO EXCEPTIONS):**
|
|
1831
|
-
1. **[RED]** Write failing test FIRST → Run test → Verify it FAILS
|
|
1832
|
-
2. **[GREEN]** Write MINIMAL code to pass → Run test → Verify it PASSES
|
|
1833
|
-
3. **[REFACTOR]** Improve code quality → Tests must stay green
|
|
1834
|
-
|
|
1835
|
-
**STRICT RULES - VIOLATIONS ARE BLOCKED:**
|
|
1836
|
-
- ❌ CANNOT write implementation before test exists
|
|
1837
|
-
- ❌ CANNOT mark [GREEN] task complete before [RED] is done
|
|
1838
|
-
- ❌ CANNOT skip the test-failure verification step
|
|
1839
|
-
- ❌ CANNOT implement features without corresponding tests
|
|
1840
|
-
|
|
1841
|
-
**BEFORE ANY IMPLEMENTATION:**
|
|
1842
|
-
1. Find or create the [RED] test task
|
|
1843
|
-
2. Write the test
|
|
1844
|
-
3. Run the test and confirm it FAILS
|
|
1845
|
-
4. Only THEN proceed to [GREEN] implementation
|
|
1846
|
-
|
|
1847
|
-
**COMMANDS:** Use \`/sw:tdd-cycle\` for guided workflow
|
|
1848
|
-
|
|
1849
|
-
---
|
|
1850
|
-
|
|
1851
|
-
**COMMANDS:** \`/sw:tdd-cycle\` for guided workflow | \`/sw:tdd-red\`, \`/sw:tdd-green\`, \`/sw:tdd-refactor\` for phases
|
|
1852
|
-
|
|
1853
|
-
---
|
|
1854
|
-
"
|
|
1617
|
+
TDD_MSG="STRICT TDD ACTIVE (source: ${TDD_SOURCE}). RED->GREEN->REFACTOR enforced. No implementation before failing test. Use /sw:tdd-cycle."
|
|
1855
1618
|
fi
|
|
1856
1619
|
|
|
1857
1620
|
# v1.0.201: Include LSP instructions BEFORE TDD message
|
|
@@ -1882,7 +1645,8 @@ fi
|
|
|
1882
1645
|
# This covers 90%+ of prompts with <5ms overhead
|
|
1883
1646
|
# v1.0.144: Still show plugin autoload message if plugins are being loaded
|
|
1884
1647
|
# v1.0.155: AUTOLOAD_PLUGINS_MSG now includes new plugin warnings from helper function
|
|
1885
|
-
|
|
1648
|
+
# v1.0.257: Expanded keywords to catch implementation prompts that bypass LLM detection
|
|
1649
|
+
if ! echo "$PROMPT" | grep -qiE "(specweave|/sw:|increment|add|create|implement|build|develop|test|component|feature|fix|refactor|write|style|setup|configure|migrate|deploy|scaffold)"; then
|
|
1886
1650
|
if [[ -n "$AUTOLOAD_PLUGINS_MSG" ]]; then
|
|
1887
1651
|
# Show plugin loading feedback even for non-SpecWeave prompts
|
|
1888
1652
|
output_approve_with_context "$AUTOLOAD_PLUGINS_MSG"
|
|
@@ -2169,6 +1933,59 @@ if [[ "$ACTIVE_COUNT" -gt 0 ]]; then
|
|
|
2169
1933
|
fi
|
|
2170
1934
|
fi
|
|
2171
1935
|
|
|
1936
|
+
# ==============================================================================
|
|
1937
|
+
# ARCHIVE SUGGESTION (v1.0.257 - Auto-archive when too many increments)
|
|
1938
|
+
# ==============================================================================
|
|
1939
|
+
# When total numbered increment directories exceed threshold, suggest archiving.
|
|
1940
|
+
# In auto mode: archive silently. Interactive: inject suggestion for LLM.
|
|
1941
|
+
# Rate-limited: once per day via marker file.
|
|
1942
|
+
ARCHIVE_SUGGESTION_MSG=""
|
|
1943
|
+
if [[ -d "$SPECWEAVE_DIR/increments" ]]; then
|
|
1944
|
+
TOTAL_INCREMENT_DIRS=$(ls -d "$SPECWEAVE_DIR/increments"/[0-9]* 2>/dev/null | wc -l | tr -d ' ')
|
|
1945
|
+
|
|
1946
|
+
# Read threshold from config (default: 10)
|
|
1947
|
+
_ARCHIVE_THRESHOLD=10
|
|
1948
|
+
if [[ -f "$CONFIG_PATH" ]] && command -v jq >/dev/null 2>&1; then
|
|
1949
|
+
_ARCHIVE_THRESHOLD=$(jq -r '.archiving.autoArchiveThreshold // 10' "$CONFIG_PATH" 2>/dev/null || echo "10")
|
|
1950
|
+
fi
|
|
1951
|
+
[[ ! "$_ARCHIVE_THRESHOLD" =~ ^[0-9]+$ ]] && _ARCHIVE_THRESHOLD=10
|
|
1952
|
+
|
|
1953
|
+
if [[ "$TOTAL_INCREMENT_DIRS" -ge "$_ARCHIVE_THRESHOLD" ]]; then
|
|
1954
|
+
# Rate limit: once per day via marker file
|
|
1955
|
+
ARCHIVE_MARKER="$SPECWEAVE_DIR/state/archive-suggestion.marker"
|
|
1956
|
+
SHOULD_SUGGEST=true
|
|
1957
|
+
if [[ -f "$ARCHIVE_MARKER" ]]; then
|
|
1958
|
+
MARKER_DATE=$(cat "$ARCHIVE_MARKER" 2>/dev/null | head -1)
|
|
1959
|
+
TODAY=$(date +%Y-%m-%d)
|
|
1960
|
+
[[ "$MARKER_DATE" == "$TODAY" ]] && SHOULD_SUGGEST=false
|
|
1961
|
+
fi
|
|
1962
|
+
|
|
1963
|
+
if [[ "$SHOULD_SUGGEST" == "true" ]]; then
|
|
1964
|
+
# Check if in auto mode
|
|
1965
|
+
AUTO_STATE_FILE="$SPECWEAVE_DIR/state/auto.json"
|
|
1966
|
+
IN_AUTO_MODE=false
|
|
1967
|
+
if [[ -f "$AUTO_STATE_FILE" ]] && command -v jq >/dev/null 2>&1; then
|
|
1968
|
+
AUTO_STATUS=$(jq -r '.status // "idle"' "$AUTO_STATE_FILE" 2>/dev/null)
|
|
1969
|
+
[[ "$AUTO_STATUS" == "running" ]] && IN_AUTO_MODE=true
|
|
1970
|
+
fi
|
|
1971
|
+
|
|
1972
|
+
if [[ "$IN_AUTO_MODE" == "true" ]]; then
|
|
1973
|
+
# Auto mode: archive silently in background
|
|
1974
|
+
if command -v specweave >/dev/null 2>&1; then
|
|
1975
|
+
specweave archive --keep-last 10 2>/dev/null &
|
|
1976
|
+
fi
|
|
1977
|
+
else
|
|
1978
|
+
# Interactive: suggest to LLM
|
|
1979
|
+
ARCHIVE_SUGGESTION_MSG="⚠️ **Archive suggested**: ${TOTAL_INCREMENT_DIRS} increments in workspace (threshold: ${_ARCHIVE_THRESHOLD}). Run: \`specweave archive --keep-last 10\`\n\n"
|
|
1980
|
+
fi
|
|
1981
|
+
|
|
1982
|
+
# Write today's date as marker
|
|
1983
|
+
mkdir -p "$(dirname "$ARCHIVE_MARKER")" 2>/dev/null
|
|
1984
|
+
echo "$(date +%Y-%m-%d)" > "$ARCHIVE_MARKER" 2>/dev/null || true
|
|
1985
|
+
fi
|
|
1986
|
+
fi
|
|
1987
|
+
fi
|
|
1988
|
+
|
|
2172
1989
|
# ==============================================================================
|
|
2173
1990
|
# SMART INTERVIEW GATE (v1.0.243 - LLM-Driven Prompt Assessment)
|
|
2174
1991
|
# ==============================================================================
|
|
@@ -2189,31 +2006,7 @@ if [[ "$DEEP_INTERVIEW_ENABLED" == "true" ]] && [[ -z "$ACTIVE_INCREMENT" ]]; th
|
|
|
2189
2006
|
fi
|
|
2190
2007
|
|
|
2191
2008
|
if [[ "$HAVE_ACTIVE_STATE" != "true" ]]; then
|
|
2192
|
-
SMART_INTERVIEW_GATE_MSG="
|
|
2193
|
-
🧠 **SMART INTERVIEW GATE** (Deep Interview Mode active, no increment yet)
|
|
2194
|
-
|
|
2195
|
-
Before proceeding, assess this conversation for completeness. Consider ALL prior messages.
|
|
2196
|
-
|
|
2197
|
-
**Assess complexity first:**
|
|
2198
|
-
- Trivial (config change, typo) → need almost nothing, proceed immediately
|
|
2199
|
-
- Small (single component) → need: tech stack + basic flow
|
|
2200
|
-
- Medium (multiple components) → need: stack + integrations + user flows + auth approach
|
|
2201
|
-
- Large (platform/multi-service) → need: architecture + security + deployment + edge cases + monitoring
|
|
2202
|
-
|
|
2203
|
-
**Check for these signals (weight by project type):**
|
|
2204
|
-
- Technical: tech stack, frameworks, database, auth method, API integrations, deployment target
|
|
2205
|
-
- Product: target users, core flows, business model, MVP scope, timeline
|
|
2206
|
-
- Operational: env vars/keys, CI/CD, monitoring needs
|
|
2207
|
-
|
|
2208
|
-
**Your decision:**
|
|
2209
|
-
- If sufficient detail for the detected complexity → call \`Skill({ skill: \\\"sw:increment-planner\\\", args: \\\"<summarize all gathered context>\\\" })\`
|
|
2210
|
-
- If gaps exist → ask 2-5 targeted questions about ONLY what is missing. Do NOT repeat questions already answered in prior messages. Do NOT run a full category-by-category interview.
|
|
2211
|
-
|
|
2212
|
-
**Rules:**
|
|
2213
|
-
- NEVER overwhelm with 10+ questions at once
|
|
2214
|
-
- NEVER ask about things the user already explained
|
|
2215
|
-
- Simple projects need fewer signals than complex platforms
|
|
2216
|
-
- When in doubt about one detail, ask — but don't block on nice-to-haves"
|
|
2009
|
+
SMART_INTERVIEW_GATE_MSG="No active increment. Assess prompt completeness for complexity — if gaps, ask 2-5 targeted questions. If sufficient, call sw:increment-planner."
|
|
2217
2010
|
fi
|
|
2218
2011
|
fi
|
|
2219
2012
|
|
|
@@ -2412,16 +2205,7 @@ fi
|
|
|
2412
2205
|
# COMMAND SUGGESTIONS: Guide users to structured workflow
|
|
2413
2206
|
# ==============================================================================
|
|
2414
2207
|
|
|
2415
|
-
|
|
2416
|
-
if [[ -n "$CONTEXT" ]]; then
|
|
2417
|
-
CONTEXT="$CONTEXT
|
|
2418
|
-
|
|
2419
|
-
💡 TIP: Consider using SpecWeave commands for structured development:
|
|
2420
|
-
- /sw:increment \"feature name\" # Plan new increment
|
|
2421
|
-
- /sw:do # Execute current tasks
|
|
2422
|
-
- /sw:progress # Check progress"
|
|
2423
|
-
fi
|
|
2424
|
-
fi
|
|
2208
|
+
# Command suggestions removed (v1.0.257) — already in CLAUDE.md, reduces per-turn context
|
|
2425
2209
|
|
|
2426
2210
|
# ==============================================================================
|
|
2427
2211
|
# STATUS LINE REFRESH (v0.26.13 - CONDITIONAL + ASYNC)
|
|
@@ -2480,6 +2264,11 @@ if [[ -n "$LSP_EXPLICIT_REQUEST_MSG" ]]; then
|
|
|
2480
2264
|
FINAL_MESSAGE="${FINAL_MESSAGE}${LSP_EXPLICIT_REQUEST_MSG}"
|
|
2481
2265
|
fi
|
|
2482
2266
|
|
|
2267
|
+
# v1.0.257: Archive suggestion when too many increments
|
|
2268
|
+
if [[ -n "$ARCHIVE_SUGGESTION_MSG" ]]; then
|
|
2269
|
+
FINAL_MESSAGE="${FINAL_MESSAGE}${ARCHIVE_SUGGESTION_MSG}"
|
|
2270
|
+
fi
|
|
2271
|
+
|
|
2483
2272
|
# v1.0.243: Smart Interview Gate for non-incrementAssist paths
|
|
2484
2273
|
# When deep interview is enabled but incrementAssist didn't trigger SKILL FIRST,
|
|
2485
2274
|
# still inject the gate so LLM can gather context across conversational prompts.
|
|
@@ -292,6 +292,20 @@ case "$FILE_PATH" in
|
|
|
292
292
|
)
|
|
293
293
|
log_debug "IMMEDIATE SYNC completed for $INC_ID"
|
|
294
294
|
fi
|
|
295
|
+
|
|
296
|
+
# ========================================================================
|
|
297
|
+
# EXPLICIT CLOSURE (v1.0.257+): Close external issues on completion
|
|
298
|
+
# ========================================================================
|
|
299
|
+
# Only on completed/done - triggers provider-agnostic closure for ALL
|
|
300
|
+
# user stories, ensuring external issues are closed even if AC sync
|
|
301
|
+
# missed them. NOT called on reopened or on every AC change.
|
|
302
|
+
if [[ "$CURRENT_STATUS" == "completed" ]] || [[ "$CURRENT_STATUS" == "done" ]]; then
|
|
303
|
+
AC_CLOSE_DISPATCHER="${HOOK_DIR}/../handlers/ac-sync-dispatcher.sh"
|
|
304
|
+
if [[ -f "$AC_CLOSE_DISPATCHER" ]]; then
|
|
305
|
+
log_debug "EXPLICIT CLOSURE: Triggering provider-agnostic closure for $INC_ID"
|
|
306
|
+
SPECWEAVE_CLOSE_ALL=1 safe_run_background "$AC_CLOSE_DISPATCHER" "ac-close" "$INC_ID"
|
|
307
|
+
fi
|
|
308
|
+
fi
|
|
295
309
|
fi
|
|
296
310
|
fi
|
|
297
311
|
;;
|
|
@@ -358,14 +372,14 @@ case "$FILE_PATH" in
|
|
|
358
372
|
fi
|
|
359
373
|
|
|
360
374
|
# ========================================================================
|
|
361
|
-
#
|
|
375
|
+
# UNIVERSAL AUTO-CREATE (v1.0.256+): Create items in ALL enabled providers
|
|
362
376
|
# ========================================================================
|
|
363
377
|
# When spec.md is created/updated AND has user stories, auto-create
|
|
364
|
-
# GitHub
|
|
378
|
+
# items in GitHub/JIRA/ADO if autoSync or auto_create is enabled.
|
|
365
379
|
if [[ "$FILE_PATH" == *spec.md ]]; then
|
|
366
|
-
|
|
367
|
-
if [[ -f "$
|
|
368
|
-
safe_run_background "$
|
|
380
|
+
UNIVERSAL_AUTO_CREATE="${HOOK_DIR}/../handlers/universal-auto-create-dispatcher.sh"
|
|
381
|
+
if [[ -f "$UNIVERSAL_AUTO_CREATE" ]]; then
|
|
382
|
+
safe_run_background "$UNIVERSAL_AUTO_CREATE" "universal-auto-create" "$INC_ID"
|
|
369
383
|
fi
|
|
370
384
|
fi
|
|
371
385
|
|
|
@@ -56,6 +56,11 @@ if [[ -z "$INC_ID" ]]; then
|
|
|
56
56
|
exit 0
|
|
57
57
|
fi
|
|
58
58
|
|
|
59
|
+
# Validate INC_ID format (defense-in-depth against injection)
|
|
60
|
+
if [[ ! "$INC_ID" =~ ^[0-9]{4}[A-Za-z0-9_-]*$ ]]; then
|
|
61
|
+
exit 0
|
|
62
|
+
fi
|
|
63
|
+
|
|
59
64
|
SPEC_PATH="$PROJECT_ROOT/.specweave/increments/$INC_ID/spec.md"
|
|
60
65
|
METADATA_PATH="$PROJECT_ROOT/.specweave/increments/$INC_ID/metadata.json"
|
|
61
66
|
CONFIG_PATH="$PROJECT_ROOT/.specweave/config.json"
|
|
@@ -114,7 +119,7 @@ for i in {1..10}; do
|
|
|
114
119
|
|
|
115
120
|
# Check for stale lock
|
|
116
121
|
if [[ -d "$LOCK_FILE" ]]; then
|
|
117
|
-
LOCK_AGE=$(($(date +%s) - $(stat -f
|
|
122
|
+
LOCK_AGE=$(($(date +%s) - $(stat -f%m "$LOCK_FILE" 2>/dev/null || stat -c%Y "$LOCK_FILE" 2>/dev/null || echo 0)))
|
|
118
123
|
if (( LOCK_AGE > LOCK_TIMEOUT )); then
|
|
119
124
|
rmdir "$LOCK_FILE" 2>/dev/null || true
|
|
120
125
|
continue
|
|
@@ -136,7 +141,7 @@ fi
|
|
|
136
141
|
SIGNAL_FILE="$STATE_DIR/.ac-sync-pending-$INC_ID"
|
|
137
142
|
|
|
138
143
|
if [[ -f "$SIGNAL_FILE" ]]; then
|
|
139
|
-
SIGNAL_AGE=$(($(date +%s) - $(stat -f
|
|
144
|
+
SIGNAL_AGE=$(($(date +%s) - $(stat -f%m "$SIGNAL_FILE" 2>/dev/null || stat -c%Y "$SIGNAL_FILE" 2>/dev/null || echo 0)))
|
|
140
145
|
if (( SIGNAL_AGE < 5 )); then
|
|
141
146
|
log "Debounce: signal file age ${SIGNAL_AGE}s < 5s. Deferring."
|
|
142
147
|
exit 0
|
|
@@ -191,6 +196,12 @@ if [[ "$AFFECTED_US_IDS" == "[]" || -z "$AFFECTED_US_IDS" ]]; then
|
|
|
191
196
|
exit 0
|
|
192
197
|
fi
|
|
193
198
|
|
|
199
|
+
# Validate AFFECTED_US_IDS is valid JSON (defense-in-depth against injection)
|
|
200
|
+
if ! echo "$AFFECTED_US_IDS" | jq empty 2>/dev/null; then
|
|
201
|
+
log "Invalid US IDs JSON. Skipping."
|
|
202
|
+
exit 0
|
|
203
|
+
fi
|
|
204
|
+
|
|
194
205
|
# ============================================================================
|
|
195
206
|
# BUILD CONFIG FROM SPECWEAVE CONFIG + METADATA
|
|
196
207
|
# ============================================================================
|
|
@@ -246,8 +257,7 @@ try {
|
|
|
246
257
|
console.error('AC sync dispatcher error:', err.message || err);
|
|
247
258
|
process.exit(1);
|
|
248
259
|
}
|
|
249
|
-
" 2>&1)
|
|
250
|
-
|
|
260
|
+
" 2>&1)
|
|
251
261
|
EXIT_CODE=$?
|
|
252
262
|
|
|
253
263
|
if [[ $EXIT_CODE -ne 0 ]]; then
|