aiwcli 0.10.1 → 0.10.3
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/dist/commands/clean.js +1 -0
- package/dist/commands/clear.d.ts +19 -2
- package/dist/commands/clear.js +351 -160
- package/dist/commands/init/index.d.ts +1 -17
- package/dist/commands/init/index.js +19 -104
- package/dist/lib/gitignore-manager.d.ts +9 -0
- package/dist/lib/gitignore-manager.js +121 -0
- package/dist/lib/template-installer.d.ts +7 -12
- package/dist/lib/template-installer.js +69 -193
- package/dist/lib/template-settings-reconstructor.d.ts +35 -0
- package/dist/lib/template-settings-reconstructor.js +130 -0
- package/dist/templates/_shared/hooks/__pycache__/archive_plan.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/session_end.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/archive_plan.py +10 -2
- package/dist/templates/_shared/hooks/session_end.py +37 -29
- package/dist/templates/_shared/lib/base/__pycache__/hook_utils.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/inference.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/logger.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/stop_words.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/utils.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/hook_utils.py +8 -10
- package/dist/templates/_shared/lib/base/inference.py +51 -62
- package/dist/templates/_shared/lib/base/logger.py +35 -21
- package/dist/templates/_shared/lib/base/stop_words.py +8 -0
- package/dist/templates/_shared/lib/base/utils.py +29 -8
- package/dist/templates/_shared/lib/context/__pycache__/plan_manager.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/plan_manager.py +101 -2
- package/dist/templates/_shared/lib-ts/base/atomic-write.ts +138 -0
- package/dist/templates/_shared/lib-ts/base/constants.ts +299 -0
- package/dist/templates/_shared/lib-ts/base/git-state.ts +58 -0
- package/dist/templates/_shared/lib-ts/base/hook-utils.ts +360 -0
- package/dist/templates/_shared/lib-ts/base/inference.ts +245 -0
- package/dist/templates/_shared/lib-ts/base/logger.ts +234 -0
- package/dist/templates/_shared/lib-ts/base/state-io.ts +114 -0
- package/dist/templates/_shared/lib-ts/base/stop-words.ts +184 -0
- package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +23 -0
- package/dist/templates/_shared/lib-ts/base/utils.ts +184 -0
- package/dist/templates/_shared/lib-ts/context/context-formatter.ts +432 -0
- package/dist/templates/_shared/lib-ts/context/context-selector.ts +497 -0
- package/dist/templates/_shared/lib-ts/context/context-store.ts +679 -0
- package/dist/templates/_shared/lib-ts/context/plan-manager.ts +292 -0
- package/dist/templates/_shared/lib-ts/context/task-tracker.ts +181 -0
- package/dist/templates/_shared/lib-ts/handoff/document-generator.ts +215 -0
- package/dist/templates/_shared/lib-ts/package.json +21 -0
- package/dist/templates/_shared/lib-ts/templates/formatters.ts +102 -0
- package/dist/templates/_shared/lib-ts/templates/plan-context.ts +65 -0
- package/dist/templates/_shared/lib-ts/tsconfig.json +13 -0
- package/dist/templates/_shared/lib-ts/types.ts +151 -0
- package/dist/templates/_shared/scripts/__pycache__/status_line.cpython-313.pyc +0 -0
- package/dist/templates/_shared/scripts/save_handoff.ts +359 -0
- package/dist/templates/_shared/scripts/status_line.py +17 -2
- package/dist/templates/cc-native/_cc-native/agents/ARCH-EVOLUTION.md +63 -0
- package/dist/templates/cc-native/_cc-native/agents/ARCH-PATTERNS.md +62 -0
- package/dist/templates/cc-native/_cc-native/agents/ARCH-STRUCTURE.md +63 -0
- package/dist/templates/cc-native/_cc-native/agents/{ASSUMPTION-CHAIN-TRACER.md → ASSUMPTION-TRACER.md} +6 -10
- package/dist/templates/cc-native/_cc-native/agents/CLARITY-AUDITOR.md +6 -10
- package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +74 -1
- package/dist/templates/cc-native/_cc-native/agents/COMPLETENESS-FEASIBILITY.md +67 -0
- package/dist/templates/cc-native/_cc-native/agents/COMPLETENESS-GAPS.md +71 -0
- package/dist/templates/cc-native/_cc-native/agents/COMPLETENESS-ORDERING.md +63 -0
- package/dist/templates/cc-native/_cc-native/agents/CONSTRAINT-VALIDATOR.md +73 -0
- package/dist/templates/cc-native/_cc-native/agents/DESIGN-ADR-VALIDATOR.md +62 -0
- package/dist/templates/cc-native/_cc-native/agents/DESIGN-SCALE-MATCHER.md +65 -0
- package/dist/templates/cc-native/_cc-native/agents/DEVILS-ADVOCATE.md +6 -9
- package/dist/templates/cc-native/_cc-native/agents/DOCUMENTATION-PHILOSOPHY.md +87 -0
- package/dist/templates/cc-native/_cc-native/agents/HANDOFF-READINESS.md +5 -9
- package/dist/templates/cc-native/_cc-native/agents/{HIDDEN-COMPLEXITY-DETECTOR.md → HIDDEN-COMPLEXITY.md} +6 -10
- package/dist/templates/cc-native/_cc-native/agents/INCREMENTAL-DELIVERY.md +67 -0
- package/dist/templates/cc-native/_cc-native/agents/PLAN-ORCHESTRATOR.md +91 -18
- package/dist/templates/cc-native/_cc-native/agents/RISK-DEPENDENCY.md +63 -0
- package/dist/templates/cc-native/_cc-native/agents/RISK-FMEA.md +67 -0
- package/dist/templates/cc-native/_cc-native/agents/RISK-PREMORTEM.md +72 -0
- package/dist/templates/cc-native/_cc-native/agents/RISK-REVERSIBILITY.md +75 -0
- package/dist/templates/cc-native/_cc-native/agents/SCOPE-BOUNDARY.md +78 -0
- package/dist/templates/cc-native/_cc-native/agents/SIMPLICITY-GUARDIAN.md +5 -9
- package/dist/templates/cc-native/_cc-native/agents/SKEPTIC.md +16 -12
- package/dist/templates/cc-native/_cc-native/agents/TESTDRIVEN-BEHAVIOR-AUDITOR.md +62 -0
- package/dist/templates/cc-native/_cc-native/agents/TESTDRIVEN-CHARACTERIZATION.md +72 -0
- package/dist/templates/cc-native/_cc-native/agents/TESTDRIVEN-FIRST-VALIDATOR.md +62 -0
- package/dist/templates/cc-native/_cc-native/agents/TESTDRIVEN-PYRAMID-ANALYZER.md +62 -0
- package/dist/templates/cc-native/_cc-native/agents/TRADEOFF-COSTS.md +68 -0
- package/dist/templates/cc-native/_cc-native/agents/TRADEOFF-STAKEHOLDERS.md +66 -0
- package/dist/templates/cc-native/_cc-native/agents/VERIFY-COVERAGE.md +75 -0
- package/dist/templates/cc-native/_cc-native/agents/VERIFY-STRENGTH.md +70 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-plan-review.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.py +125 -40
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/utils.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/utils.py +57 -13
- package/dist/templates/cc-native/_cc-native/plan-review.config.json +11 -7
- package/oclif.manifest.json +17 -2
- package/package.json +1 -1
- package/dist/lib/template-merger.d.ts +0 -47
- package/dist/lib/template-merger.js +0 -162
- package/dist/templates/cc-native/_cc-native/agents/ACCESSIBILITY-TESTER.md +0 -79
- package/dist/templates/cc-native/_cc-native/agents/ARCHITECT-REVIEWER.md +0 -48
- package/dist/templates/cc-native/_cc-native/agents/CODE-REVIEWER.md +0 -70
- package/dist/templates/cc-native/_cc-native/agents/COMPLETENESS-CHECKER.md +0 -59
- package/dist/templates/cc-native/_cc-native/agents/CONTEXT-EXTRACTOR.md +0 -92
- package/dist/templates/cc-native/_cc-native/agents/DOCUMENTATION-REVIEWER.md +0 -51
- package/dist/templates/cc-native/_cc-native/agents/FEASIBILITY-ANALYST.md +0 -57
- package/dist/templates/cc-native/_cc-native/agents/FRESH-PERSPECTIVE.md +0 -54
- package/dist/templates/cc-native/_cc-native/agents/INCENTIVE-MAPPER.md +0 -61
- package/dist/templates/cc-native/_cc-native/agents/PENETRATION-TESTER.md +0 -79
- package/dist/templates/cc-native/_cc-native/agents/PERFORMANCE-ENGINEER.md +0 -75
- package/dist/templates/cc-native/_cc-native/agents/PRECEDENT-FINDER.md +0 -70
- package/dist/templates/cc-native/_cc-native/agents/REVERSIBILITY-ANALYST.md +0 -61
- package/dist/templates/cc-native/_cc-native/agents/RISK-ASSESSOR.md +0 -58
- package/dist/templates/cc-native/_cc-native/agents/SECOND-ORDER-ANALYST.md +0 -61
- package/dist/templates/cc-native/_cc-native/agents/STAKEHOLDER-ADVOCATE.md +0 -55
- package/dist/templates/cc-native/_cc-native/agents/TRADE-OFF-ILLUMINATOR.md +0 -204
|
@@ -153,13 +153,18 @@ def is_plan_already_reviewed(session_id: str, plan_hash: str) -> bool:
|
|
|
153
153
|
|
|
154
154
|
|
|
155
155
|
def was_plan_previously_denied(session_id: str, plan_hash: str) -> bool:
|
|
156
|
-
"""Check if this plan hash was previously reviewed and denied.
|
|
156
|
+
"""Check if this plan hash was previously reviewed and denied.
|
|
157
|
+
|
|
158
|
+
Matches any deny variant: "deny", "hook_deny_iteration", "hook_deny_final".
|
|
159
|
+
"""
|
|
157
160
|
marker_path = get_review_marker_path(session_id)
|
|
158
161
|
if not marker_path.exists():
|
|
159
162
|
return False
|
|
160
163
|
try:
|
|
161
164
|
data = json.loads(marker_path.read_text(encoding="utf-8"))
|
|
162
|
-
|
|
165
|
+
decision = data.get("decision", "")
|
|
166
|
+
is_denied = decision == "deny" or decision.startswith("hook_deny")
|
|
167
|
+
return data.get("plan_hash") == plan_hash and is_denied
|
|
163
168
|
except Exception:
|
|
164
169
|
return False
|
|
165
170
|
|
|
@@ -362,13 +367,15 @@ def compute_review_decision(
|
|
|
362
367
|
all_verdicts: List[str],
|
|
363
368
|
warn_threshold: float = 0.5,
|
|
364
369
|
) -> Tuple[bool, str, float]:
|
|
365
|
-
"""Verdict aggregation:
|
|
370
|
+
"""Verdict aggregation: fail veto triggers a block.
|
|
366
371
|
|
|
367
|
-
|
|
368
|
-
|
|
372
|
+
Per-agent high-severity override happens upstream (caller overrides
|
|
373
|
+
individual agent verdicts to "fail" when they exceed the threshold),
|
|
374
|
+
so this function only needs fail_veto logic.
|
|
369
375
|
|
|
370
|
-
|
|
371
|
-
|
|
376
|
+
Priority order:
|
|
377
|
+
1. Fail Veto: Any fail -> deny (ISO 61508 zero-tolerance).
|
|
378
|
+
2. Acceptable: warns are informational only.
|
|
372
379
|
|
|
373
380
|
Error exclusion: Detectors that produce no signal (error/skip) are excluded
|
|
374
381
|
from the denominator. They provide no information about plan quality.
|
|
@@ -381,7 +388,7 @@ def compute_review_decision(
|
|
|
381
388
|
Tuple of (should_deny, reason, score).
|
|
382
389
|
- should_deny: True if the plan should be denied.
|
|
383
390
|
- reason: "fail_veto", "acceptable", or "no_signal".
|
|
384
|
-
- score: 1.0 for
|
|
391
|
+
- score: 1.0 for deny cases, warn_ratio for informational, 0.0 for no_signal.
|
|
385
392
|
"""
|
|
386
393
|
# Exclude non-signal verdicts
|
|
387
394
|
signal_verdicts = [v for v in all_verdicts if v in ("pass", "warn", "fail")]
|
|
@@ -389,7 +396,7 @@ def compute_review_decision(
|
|
|
389
396
|
if not signal_verdicts:
|
|
390
397
|
return False, "no_signal", 0.0
|
|
391
398
|
|
|
392
|
-
#
|
|
399
|
+
# Fail blocks unconditionally
|
|
393
400
|
fail_count = signal_verdicts.count("fail")
|
|
394
401
|
if fail_count > 0:
|
|
395
402
|
return True, "fail_veto", 1.0
|
|
@@ -677,13 +684,17 @@ def extract_top_issues_text(
|
|
|
677
684
|
) -> str:
|
|
678
685
|
"""Extract top issues as a compact text string for permissionDecisionReason.
|
|
679
686
|
|
|
687
|
+
Collects the first matching issue from each reviewer/agent, prefixed with
|
|
688
|
+
the reviewer name for attribution. This gives breadth across agents rather
|
|
689
|
+
than depth from a single one.
|
|
690
|
+
|
|
680
691
|
Args:
|
|
681
692
|
combined: The combined review result.
|
|
682
693
|
max_count: Maximum number of issues to include.
|
|
683
694
|
severity: Severity level to filter for.
|
|
684
695
|
|
|
685
696
|
Returns:
|
|
686
|
-
Compact semicolon-separated issue text.
|
|
697
|
+
Compact semicolon-separated issue text with agent attribution.
|
|
687
698
|
"""
|
|
688
699
|
all_reviewers: List[ReviewerResult] = []
|
|
689
700
|
all_reviewers.extend(combined.cli_reviewers.values())
|
|
@@ -697,9 +708,8 @@ def extract_top_issues_text(
|
|
|
697
708
|
if issue.get("severity") == severity:
|
|
698
709
|
text = issue.get("issue", "").strip()
|
|
699
710
|
if text:
|
|
700
|
-
issues.append(text)
|
|
701
|
-
|
|
702
|
-
break
|
|
711
|
+
issues.append(f"[{r.name}] {text}")
|
|
712
|
+
break # first high issue per reviewer only
|
|
703
713
|
if len(issues) >= max_count:
|
|
704
714
|
break
|
|
705
715
|
|
|
@@ -708,6 +718,40 @@ def extract_top_issues_text(
|
|
|
708
718
|
return "; ".join(issues)
|
|
709
719
|
|
|
710
720
|
|
|
721
|
+
def build_high_issues_document(combined: CombinedReviewResult) -> str:
|
|
722
|
+
"""Build a markdown document containing ONLY high-severity issues.
|
|
723
|
+
|
|
724
|
+
Grouped by reviewer/agent name with issue text and suggested fix.
|
|
725
|
+
This is the primary signal document for plan revision — high severity
|
|
726
|
+
only, no noise from medium/low issues.
|
|
727
|
+
"""
|
|
728
|
+
lines = ["# High-Severity Issues\n"]
|
|
729
|
+
all_reviewers = list(combined.cli_reviewers.values()) + list(combined.agents.values())
|
|
730
|
+
|
|
731
|
+
found_any = False
|
|
732
|
+
for r in all_reviewers:
|
|
733
|
+
if not r.data:
|
|
734
|
+
continue
|
|
735
|
+
high_issues = [i for i in r.data.get("issues", []) if i.get("severity") == "high"]
|
|
736
|
+
if not high_issues:
|
|
737
|
+
continue
|
|
738
|
+
found_any = True
|
|
739
|
+
lines.append(f"## {r.name} ({r.verdict})\n")
|
|
740
|
+
for issue in high_issues:
|
|
741
|
+
cat = issue.get("category", "general")
|
|
742
|
+
text = issue.get("issue", "").strip()
|
|
743
|
+
fix = issue.get("suggested_fix", "").strip()
|
|
744
|
+
lines.append(f"- **[{cat}]** {text}")
|
|
745
|
+
if fix:
|
|
746
|
+
lines.append(f" - Fix: {fix}")
|
|
747
|
+
lines.append("") # blank line between agents
|
|
748
|
+
|
|
749
|
+
if not found_any:
|
|
750
|
+
lines.append("No high-severity issues found.\n")
|
|
751
|
+
|
|
752
|
+
return "\n".join(lines)
|
|
753
|
+
|
|
754
|
+
|
|
711
755
|
def _append_review_details(
|
|
712
756
|
lines: List[str],
|
|
713
757
|
data: Dict[str, Any],
|
|
@@ -25,21 +25,25 @@
|
|
|
25
25
|
"warnThreshold": 0.01,
|
|
26
26
|
"orchestrator": {
|
|
27
27
|
"enabled": true,
|
|
28
|
-
"model": "
|
|
29
|
-
"timeout":
|
|
28
|
+
"model": "opus",
|
|
29
|
+
"timeout": 60
|
|
30
30
|
},
|
|
31
31
|
"legacyMode": false,
|
|
32
|
-
"mandatoryAgents":
|
|
32
|
+
"mandatoryAgents": {
|
|
33
|
+
"always": ["handoff-readiness", "clarity-auditor", "skeptic"],
|
|
34
|
+
"medium+": ["documentation-philosophy"]
|
|
35
|
+
},
|
|
33
36
|
"fallbackByComplexity": {
|
|
34
37
|
"simple": 0,
|
|
35
|
-
"medium":
|
|
36
|
-
"high":
|
|
38
|
+
"medium": 12,
|
|
39
|
+
"high": 6
|
|
37
40
|
},
|
|
38
41
|
"reviewIterations": {
|
|
39
42
|
"simple": 1,
|
|
40
43
|
"medium": 1,
|
|
41
44
|
"high": 2
|
|
42
45
|
},
|
|
46
|
+
"highIssueThreshold": 2,
|
|
43
47
|
"earlyExitOnAllPass": true,
|
|
44
48
|
"display": {
|
|
45
49
|
"maxIssues": 12,
|
|
@@ -49,8 +53,8 @@
|
|
|
49
53
|
},
|
|
50
54
|
"agentSelection": {
|
|
51
55
|
"simple": { "min": 3, "max": 3 },
|
|
52
|
-
"medium": { "min":
|
|
53
|
-
"high": { "min":
|
|
56
|
+
"medium": { "min": 12, "max": 12 },
|
|
57
|
+
"high": { "min": 6, "max": 6 },
|
|
54
58
|
"fallbackCount": 3
|
|
55
59
|
},
|
|
56
60
|
"agentDefaults": {
|
package/oclif.manifest.json
CHANGED
|
@@ -195,7 +195,9 @@
|
|
|
195
195
|
"<%= config.bin %> <%= command.id %> --template cc-native",
|
|
196
196
|
"<%= config.bin %> <%= command.id %> -t cc-native",
|
|
197
197
|
"<%= config.bin %> <%= command.id %> --dry-run",
|
|
198
|
-
"<%= config.bin %> <%= command.id %> --force"
|
|
198
|
+
"<%= config.bin %> <%= command.id %> --force",
|
|
199
|
+
"<%= config.bin %> <%= command.id %> --output",
|
|
200
|
+
"<%= config.bin %> <%= command.id %> --output --dry-run"
|
|
199
201
|
],
|
|
200
202
|
"flags": {
|
|
201
203
|
"debug": {
|
|
@@ -233,9 +235,22 @@
|
|
|
233
235
|
"allowNo": false,
|
|
234
236
|
"type": "boolean"
|
|
235
237
|
},
|
|
238
|
+
"output": {
|
|
239
|
+
"char": "o",
|
|
240
|
+
"description": "Clean runtime output artifacts (temp files, caches, log rotation, archives)",
|
|
241
|
+
"exclusive": [
|
|
242
|
+
"template"
|
|
243
|
+
],
|
|
244
|
+
"name": "output",
|
|
245
|
+
"allowNo": false,
|
|
246
|
+
"type": "boolean"
|
|
247
|
+
},
|
|
236
248
|
"template": {
|
|
237
249
|
"char": "t",
|
|
238
250
|
"description": "Clear only a specific template (e.g., cc-native)",
|
|
251
|
+
"exclusive": [
|
|
252
|
+
"output"
|
|
253
|
+
],
|
|
239
254
|
"name": "template",
|
|
240
255
|
"hasDynamicHelp": false,
|
|
241
256
|
"multiple": false,
|
|
@@ -401,5 +416,5 @@
|
|
|
401
416
|
]
|
|
402
417
|
}
|
|
403
418
|
},
|
|
404
|
-
"version": "0.10.
|
|
419
|
+
"version": "0.10.3"
|
|
405
420
|
}
|
package/package.json
CHANGED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Content folder types that should be recursively merged rather than skipped.
|
|
3
|
-
* These are the canonical folder names used in templates for organizing content.
|
|
4
|
-
*/
|
|
5
|
-
export declare const CONTENT_FOLDER_TYPES: readonly ["agents", "commands", "workflows", "tasks"];
|
|
6
|
-
/**
|
|
7
|
-
* Result of merging content folders
|
|
8
|
-
*/
|
|
9
|
-
export interface MergeResult {
|
|
10
|
-
/** Files that were copied */
|
|
11
|
-
copiedFiles: string[];
|
|
12
|
-
/** Directories that were created */
|
|
13
|
-
createdDirs: string[];
|
|
14
|
-
/** Files that were skipped (already exist) */
|
|
15
|
-
skippedFiles: string[];
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Recursively find folders matching the method name within a directory tree.
|
|
19
|
-
* This finds folders like `.claude/commands/bmad/` when methodName is 'bmad'.
|
|
20
|
-
*
|
|
21
|
-
* @param dir - Directory to search
|
|
22
|
-
* @param methodName - Method name to look for (e.g., 'bmad', 'gsd')
|
|
23
|
-
* @returns Array of paths to matching folders
|
|
24
|
-
*/
|
|
25
|
-
export declare function findMethodFolders(dir: string, methodName: string): Promise<string[]>;
|
|
26
|
-
/**
|
|
27
|
-
* Merge template content into an existing IDE folder.
|
|
28
|
-
* Recursively finds folders matching the method name and merges their content.
|
|
29
|
-
*
|
|
30
|
-
* This enables adding new agents, commands, workflows, and tasks from a template
|
|
31
|
-
* even when the IDE folder (e.g., .claude) already exists.
|
|
32
|
-
*
|
|
33
|
-
* @param templateIdePath - Path to the template's IDE folder (e.g., template/.claude)
|
|
34
|
-
* @param targetIdePath - Path to the target's IDE folder (e.g., project/.claude)
|
|
35
|
-
* @param methodName - Method name to look for (e.g., 'bmad', 'gsd')
|
|
36
|
-
* @returns Merge results
|
|
37
|
-
*/
|
|
38
|
-
export declare function mergeTemplateContent(templateIdePath: string, targetIdePath: string, methodName: string): Promise<MergeResult>;
|
|
39
|
-
/**
|
|
40
|
-
* Merge content type folders (agents, commands, workflows, tasks) from template to target.
|
|
41
|
-
* This is an alternative approach that looks for specific folder types rather than method names.
|
|
42
|
-
*
|
|
43
|
-
* @param templateIdePath - Path to the template's IDE folder
|
|
44
|
-
* @param targetIdePath - Path to the target's IDE folder
|
|
45
|
-
* @returns Merge results
|
|
46
|
-
*/
|
|
47
|
-
export declare function mergeContentTypeFolders(templateIdePath: string, targetIdePath: string): Promise<MergeResult>;
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { pathExists } from './paths.js';
|
|
4
|
-
/**
|
|
5
|
-
* Content folder types that should be recursively merged rather than skipped.
|
|
6
|
-
* These are the canonical folder names used in templates for organizing content.
|
|
7
|
-
*/
|
|
8
|
-
export const CONTENT_FOLDER_TYPES = ['agents', 'commands', 'workflows', 'tasks'];
|
|
9
|
-
/**
|
|
10
|
-
* Recursively find folders matching the method name within a directory tree.
|
|
11
|
-
* This finds folders like `.claude/commands/bmad/` when methodName is 'bmad'.
|
|
12
|
-
*
|
|
13
|
-
* @param dir - Directory to search
|
|
14
|
-
* @param methodName - Method name to look for (e.g., 'bmad', 'gsd')
|
|
15
|
-
* @returns Array of paths to matching folders
|
|
16
|
-
*/
|
|
17
|
-
export async function findMethodFolders(dir, methodName) {
|
|
18
|
-
const results = [];
|
|
19
|
-
async function scan(currentDir) {
|
|
20
|
-
try {
|
|
21
|
-
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
22
|
-
const directories = entries.filter((entry) => entry.isDirectory());
|
|
23
|
-
// Process all directories in parallel
|
|
24
|
-
await Promise.all(directories.map(async (entry) => {
|
|
25
|
-
const entryPath = join(currentDir, entry.name);
|
|
26
|
-
if (entry.name === methodName) {
|
|
27
|
-
results.push(entryPath);
|
|
28
|
-
}
|
|
29
|
-
// Recursively scan subdirectories
|
|
30
|
-
await scan(entryPath);
|
|
31
|
-
}));
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
// Ignore errors (permission issues, etc.)
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
await scan(dir);
|
|
38
|
-
return results;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Recursively merge a source directory into a target directory.
|
|
42
|
-
* Only copies files that don't already exist in the target.
|
|
43
|
-
* Creates directories as needed.
|
|
44
|
-
*
|
|
45
|
-
* @param srcDir - Source directory to copy from
|
|
46
|
-
* @param destDir - Destination directory to copy to
|
|
47
|
-
* @param result - Accumulator for merge results
|
|
48
|
-
*/
|
|
49
|
-
async function mergeDirectory(srcDir, destDir, result) {
|
|
50
|
-
// Create destination directory if it doesn't exist
|
|
51
|
-
if (!(await pathExists(destDir))) {
|
|
52
|
-
await fs.mkdir(destDir, { recursive: true });
|
|
53
|
-
result.createdDirs.push(destDir);
|
|
54
|
-
}
|
|
55
|
-
const entries = await fs.readdir(srcDir, { withFileTypes: true });
|
|
56
|
-
// Process all entries in parallel
|
|
57
|
-
await Promise.all(entries.map(async (entry) => {
|
|
58
|
-
const srcPath = join(srcDir, entry.name);
|
|
59
|
-
const destPath = join(destDir, entry.name);
|
|
60
|
-
if (entry.isDirectory()) {
|
|
61
|
-
// Recursively merge subdirectories
|
|
62
|
-
await mergeDirectory(srcPath, destPath, result);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
// Copy file if it doesn't exist
|
|
66
|
-
const exists = await pathExists(destPath);
|
|
67
|
-
if (exists) {
|
|
68
|
-
result.skippedFiles.push(destPath);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
await fs.copyFile(srcPath, destPath);
|
|
72
|
-
result.copiedFiles.push(destPath);
|
|
73
|
-
}
|
|
74
|
-
}));
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Merge template content into an existing IDE folder.
|
|
78
|
-
* Recursively finds folders matching the method name and merges their content.
|
|
79
|
-
*
|
|
80
|
-
* This enables adding new agents, commands, workflows, and tasks from a template
|
|
81
|
-
* even when the IDE folder (e.g., .claude) already exists.
|
|
82
|
-
*
|
|
83
|
-
* @param templateIdePath - Path to the template's IDE folder (e.g., template/.claude)
|
|
84
|
-
* @param targetIdePath - Path to the target's IDE folder (e.g., project/.claude)
|
|
85
|
-
* @param methodName - Method name to look for (e.g., 'bmad', 'gsd')
|
|
86
|
-
* @returns Merge results
|
|
87
|
-
*/
|
|
88
|
-
export async function mergeTemplateContent(templateIdePath, targetIdePath, methodName) {
|
|
89
|
-
const result = {
|
|
90
|
-
copiedFiles: [],
|
|
91
|
-
createdDirs: [],
|
|
92
|
-
skippedFiles: [],
|
|
93
|
-
};
|
|
94
|
-
// First, copy root-level files from the template IDE folder (e.g., settings.json)
|
|
95
|
-
// These are files directly in .claude/ that aren't in method-specific subfolders
|
|
96
|
-
try {
|
|
97
|
-
const entries = await fs.readdir(templateIdePath, { withFileTypes: true });
|
|
98
|
-
const rootFiles = entries.filter((entry) => entry.isFile());
|
|
99
|
-
await Promise.all(rootFiles.map(async (file) => {
|
|
100
|
-
const srcPath = join(templateIdePath, file.name);
|
|
101
|
-
const destPath = join(targetIdePath, file.name);
|
|
102
|
-
// Only copy if it doesn't exist (skip existing behavior)
|
|
103
|
-
const exists = await pathExists(destPath);
|
|
104
|
-
if (exists) {
|
|
105
|
-
result.skippedFiles.push(destPath);
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
await fs.copyFile(srcPath, destPath);
|
|
109
|
-
result.copiedFiles.push(destPath);
|
|
110
|
-
}
|
|
111
|
-
}));
|
|
112
|
-
}
|
|
113
|
-
catch {
|
|
114
|
-
// Ignore errors (permission issues, missing directory, etc.)
|
|
115
|
-
}
|
|
116
|
-
// Find all folders matching the method name in the template
|
|
117
|
-
const methodFolders = await findMethodFolders(templateIdePath, methodName);
|
|
118
|
-
// Merge all method folders in parallel
|
|
119
|
-
await Promise.all(methodFolders.map(async (srcMethodFolder) => {
|
|
120
|
-
// Calculate the relative path from the template IDE folder
|
|
121
|
-
const relativePath = srcMethodFolder.slice(templateIdePath.length);
|
|
122
|
-
const destMethodFolder = join(targetIdePath, relativePath);
|
|
123
|
-
// Merge this method folder into the target
|
|
124
|
-
await mergeDirectory(srcMethodFolder, destMethodFolder, result);
|
|
125
|
-
}));
|
|
126
|
-
return result;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Merge content type folders (agents, commands, workflows, tasks) from template to target.
|
|
130
|
-
* This is an alternative approach that looks for specific folder types rather than method names.
|
|
131
|
-
*
|
|
132
|
-
* @param templateIdePath - Path to the template's IDE folder
|
|
133
|
-
* @param targetIdePath - Path to the target's IDE folder
|
|
134
|
-
* @returns Merge results
|
|
135
|
-
*/
|
|
136
|
-
export async function mergeContentTypeFolders(templateIdePath, targetIdePath) {
|
|
137
|
-
const result = {
|
|
138
|
-
copiedFiles: [],
|
|
139
|
-
createdDirs: [],
|
|
140
|
-
skippedFiles: [],
|
|
141
|
-
};
|
|
142
|
-
async function scanAndMerge(srcDir, destDir) {
|
|
143
|
-
try {
|
|
144
|
-
const entries = await fs.readdir(srcDir, { withFileTypes: true });
|
|
145
|
-
const directories = entries.filter((entry) => entry.isDirectory());
|
|
146
|
-
// Process all directories in parallel
|
|
147
|
-
await Promise.all(directories.map(async (entry) => {
|
|
148
|
-
const srcPath = join(srcDir, entry.name);
|
|
149
|
-
const destPath = join(destDir, entry.name);
|
|
150
|
-
// Check if this is a content type folder
|
|
151
|
-
const isContentType = CONTENT_FOLDER_TYPES.includes(entry.name);
|
|
152
|
-
// Merge content folders, recursively scan other directories
|
|
153
|
-
await (isContentType ? mergeDirectory(srcPath, destPath, result) : scanAndMerge(srcPath, destPath));
|
|
154
|
-
}));
|
|
155
|
-
}
|
|
156
|
-
catch {
|
|
157
|
-
// Ignore errors
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
await scanAndMerge(templateIdePath, targetIdePath);
|
|
161
|
-
return result;
|
|
162
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: accessibility-tester
|
|
3
|
-
description: Expert accessibility tester specializing in WCAG compliance, inclusive design, and universal access. Masters screen reader compatibility, keyboard navigation, and assistive technology integration with focus on creating barrier-free digital experiences.
|
|
4
|
-
model: sonnet
|
|
5
|
-
focus: accessibility compliance and UX concerns
|
|
6
|
-
enabled: false
|
|
7
|
-
categories:
|
|
8
|
-
- code
|
|
9
|
-
- design
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Role
|
|
13
|
-
|
|
14
|
-
Senior accessibility tester with expertise in WCAG 2.1/2.2 standards, assistive technologies, and inclusive design principles. Focus on visual, auditory, motor, and cognitive accessibility with emphasis on creating universally accessible digital experiences.
|
|
15
|
-
|
|
16
|
-
## Compliance Framework
|
|
17
|
-
|
|
18
|
-
Target: WCAG 2.1 Level AA minimum. Evaluate against four principles: Perceivable, Operable, Understandable, Robust (POUR).
|
|
19
|
-
|
|
20
|
-
## Testing Focus
|
|
21
|
-
|
|
22
|
-
### 1. Screen Reader Compatibility
|
|
23
|
-
Content announcement order, interactive element labeling, live region behavior, ARIA roles/states/properties, landmark navigation, and table structure.
|
|
24
|
-
|
|
25
|
-
### 2. Keyboard Navigation
|
|
26
|
-
Logical tab order, visible focus indicators, skip links, keyboard shortcuts, focus trapping prevention, modal accessibility, and form interaction.
|
|
27
|
-
|
|
28
|
-
### 3. Visual Accessibility
|
|
29
|
-
Color contrast ratios (4.5:1 text, 3:1 UI), text scalability to 200%, motion controls, high contrast mode support, and responsive layout stability.
|
|
30
|
-
|
|
31
|
-
## Output Format
|
|
32
|
-
|
|
33
|
-
**Example 1: Screen Reader Issue**
|
|
34
|
-
```
|
|
35
|
-
CRITICAL: Missing accessible name on submit button - components/Form.tsx:45
|
|
36
|
-
- Element: `<button><svg>...</svg></button>`
|
|
37
|
-
- Issue: Screen readers announce "button" with no context
|
|
38
|
-
- Fix: Add aria-label: `<button aria-label="Submit form"><svg>...</svg></button>`
|
|
39
|
-
- WCAG: 4.1.2 Name, Role, Value (Level A)
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
**Example 2: Keyboard Issue**
|
|
43
|
-
```
|
|
44
|
-
HIGH: Focus trap in modal dialog - components/Modal.tsx:23
|
|
45
|
-
- Issue: Tab key escapes modal to background content
|
|
46
|
-
- Impact: Keyboard users lose context, cannot complete task
|
|
47
|
-
- Fix: Implement focus trap: cycle focus within modal, restore on close
|
|
48
|
-
- WCAG: 2.4.3 Focus Order (Level A)
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Process
|
|
52
|
-
|
|
53
|
-
1. Run automated accessibility scan (axe, Lighthouse)
|
|
54
|
-
2. Perform keyboard-only navigation test
|
|
55
|
-
3. Test with screen reader (NVDA, VoiceOver, or JAWS)
|
|
56
|
-
4. Verify color contrast and visual requirements
|
|
57
|
-
|
|
58
|
-
## Communication Protocol
|
|
59
|
-
|
|
60
|
-
Request accessibility context when starting:
|
|
61
|
-
```json
|
|
62
|
-
{
|
|
63
|
-
"requesting_agent": "accessibility-tester",
|
|
64
|
-
"request_type": "get_accessibility_context",
|
|
65
|
-
"payload": {
|
|
66
|
-
"query": "Accessibility context needed: application type, compliance requirements, known issues, and platform targets."
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Assessment Completion
|
|
72
|
-
|
|
73
|
-
Report findings with WCAG mapping:
|
|
74
|
-
- Specific element and location
|
|
75
|
-
- Clear problem description with user impact
|
|
76
|
-
- Concrete fix with code example
|
|
77
|
-
- WCAG success criterion reference
|
|
78
|
-
|
|
79
|
-
Prioritize user needs and universal design principles while creating inclusive experiences that work for everyone regardless of ability.
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: architect-reviewer
|
|
3
|
-
description: Expert architecture reviewer specializing in system design validation, architectural patterns, and technical decision assessment. Masters scalability analysis, technology stack evaluation, and evolutionary architecture with focus on maintainability and long-term viability.
|
|
4
|
-
model: sonnet
|
|
5
|
-
focus: architectural concerns and scalability
|
|
6
|
-
enabled: false
|
|
7
|
-
categories:
|
|
8
|
-
- code
|
|
9
|
-
- infrastructure
|
|
10
|
-
- design
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# Architect Reviewer - Plan Review Agent
|
|
14
|
-
|
|
15
|
-
Senior architecture reviewer evaluating system designs, architectural decisions, and technology choices.
|
|
16
|
-
|
|
17
|
-
## Your Expertise
|
|
18
|
-
|
|
19
|
-
### 1. Design Patterns & Structure
|
|
20
|
-
Component boundaries, service contracts, dependency management, coupling/cohesion balance, appropriate pattern selection (microservices, event-driven, layered), and domain-driven design alignment.
|
|
21
|
-
|
|
22
|
-
### 2. Scalability & Performance Architecture
|
|
23
|
-
Horizontal/vertical scaling readiness, data partitioning strategy, caching layers, load distribution, database scaling approach, and performance bottleneck potential.
|
|
24
|
-
|
|
25
|
-
### 3. Technical Debt & Evolution
|
|
26
|
-
Architecture smells, technology obsolescence risks, complexity metrics, maintenance burden assessment, modernization path clarity, and reversibility of decisions.
|
|
27
|
-
|
|
28
|
-
## CRITICAL: Single-Turn Review
|
|
29
|
-
|
|
30
|
-
When reviewing a plan, you MUST:
|
|
31
|
-
1. Analyze the plan content provided directly (do NOT use Read, Write, Edit, Bash, Glob, Grep, or any tools)
|
|
32
|
-
2. Call StructuredOutput IMMEDIATELY with your assessment
|
|
33
|
-
3. Complete your entire review in ONE response
|
|
34
|
-
|
|
35
|
-
Do NOT:
|
|
36
|
-
- Query context managers or external systems
|
|
37
|
-
- Read files from the codebase
|
|
38
|
-
- Request architecture documentation
|
|
39
|
-
- Ask follow-up questions
|
|
40
|
-
|
|
41
|
-
## Required Output
|
|
42
|
-
|
|
43
|
-
Call StructuredOutput with exactly these fields:
|
|
44
|
-
- **verdict**: "pass" (architecturally sound), "warn" (some concerns), or "fail" (critical architectural issues)
|
|
45
|
-
- **summary**: 2-3 sentences explaining your architectural assessment (minimum 20 characters)
|
|
46
|
-
- **issues**: Array of architectural concerns, each with: severity (high/medium/low), category (e.g., "coupling", "scalability", "tech-debt"), issue description, suggested_fix
|
|
47
|
-
- **missing_sections**: Architectural considerations the plan should address but doesn't
|
|
48
|
-
- **questions**: Design decisions that need clarification before implementation
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: code-reviewer
|
|
3
|
-
description: Expert code reviewer specializing in code quality, security vulnerabilities, and best practices across multiple languages. Masters static analysis, design patterns, and performance optimization with focus on maintainability and technical debt reduction.
|
|
4
|
-
model: sonnet
|
|
5
|
-
focus: code quality and security
|
|
6
|
-
enabled: false
|
|
7
|
-
categories:
|
|
8
|
-
- code
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Role
|
|
12
|
-
|
|
13
|
-
Senior code reviewer with expertise in identifying code quality issues, security vulnerabilities, and optimization opportunities across multiple programming languages. Focus on correctness, performance, maintainability, and security with emphasis on constructive, actionable feedback.
|
|
14
|
-
|
|
15
|
-
## Review Focus
|
|
16
|
-
|
|
17
|
-
### 1. Security (Highest Priority)
|
|
18
|
-
Input validation, injection vulnerabilities (SQL, XSS, command), authentication/authorization flaws, sensitive data exposure, cryptographic weaknesses, and dependency vulnerabilities.
|
|
19
|
-
|
|
20
|
-
### 2. Correctness
|
|
21
|
-
Logic errors, error handling gaps, resource management (leaks, race conditions), edge case coverage, and test quality.
|
|
22
|
-
|
|
23
|
-
### 3. Maintainability
|
|
24
|
-
SOLID principles compliance, code organization, naming clarity, appropriate abstraction levels, duplication, and documentation completeness.
|
|
25
|
-
|
|
26
|
-
## Output Format
|
|
27
|
-
|
|
28
|
-
**Example 1: Security Finding**
|
|
29
|
-
```
|
|
30
|
-
CRITICAL: SQL Injection in user_service.py:47
|
|
31
|
-
- `query = f"SELECT * FROM users WHERE id = {user_id}"` allows injection
|
|
32
|
-
- Fix: Use parameterized queries: `cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))`
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
**Example 2: Maintainability Finding**
|
|
36
|
-
```
|
|
37
|
-
MEDIUM: High cyclomatic complexity in process_order() - handlers/orders.py:112
|
|
38
|
-
- Current complexity: 15 (threshold: 10)
|
|
39
|
-
- Suggestion: Extract validation logic into separate functions
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Process
|
|
43
|
-
|
|
44
|
-
1. Read the code changes thoroughly before commenting
|
|
45
|
-
2. Prioritize security issues, then correctness, then maintainability
|
|
46
|
-
3. Provide specific line references and concrete fix suggestions
|
|
47
|
-
4. Acknowledge good practices alongside issues
|
|
48
|
-
|
|
49
|
-
## Communication Protocol
|
|
50
|
-
|
|
51
|
-
Request review context when starting:
|
|
52
|
-
```json
|
|
53
|
-
{
|
|
54
|
-
"requesting_agent": "code-reviewer",
|
|
55
|
-
"request_type": "get_review_context",
|
|
56
|
-
"payload": {
|
|
57
|
-
"query": "Code review context needed: language, coding standards, security requirements, and review scope."
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Review Completion
|
|
63
|
-
|
|
64
|
-
Report findings structured by severity (critical → high → medium → low) with:
|
|
65
|
-
- Specific file and line references
|
|
66
|
-
- Clear problem description
|
|
67
|
-
- Concrete fix suggestion
|
|
68
|
-
- Impact assessment
|
|
69
|
-
|
|
70
|
-
Prioritize security, correctness, and maintainability while providing constructive feedback that helps improve code quality.
|