aiwcli 0.10.2 → 0.11.0
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/bin/run.js +1 -1
- package/dist/commands/clear.d.ts +11 -6
- package/dist/commands/clear.js +229 -381
- package/dist/commands/init/index.d.ts +1 -17
- package/dist/commands/init/index.js +22 -107
- package/dist/lib/gitignore-manager.d.ts +32 -0
- package/dist/lib/gitignore-manager.js +141 -2
- 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/CLAUDE.md +8 -8
- package/dist/templates/_shared/.claude/commands/handoff-resume.md +64 -0
- package/dist/templates/_shared/.claude/commands/handoff.md +16 -10
- package/dist/templates/_shared/.claude/settings.json +7 -7
- package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +2 -0
- package/dist/templates/_shared/hooks-ts/archive_plan.ts +159 -0
- package/dist/templates/_shared/hooks-ts/context_monitor.ts +147 -0
- package/dist/templates/_shared/hooks-ts/file-suggestion.ts +130 -0
- package/dist/templates/_shared/hooks-ts/pre_compact.ts +49 -0
- package/dist/templates/_shared/hooks-ts/session_end.ts +104 -0
- package/dist/templates/_shared/hooks-ts/session_start.ts +144 -0
- package/dist/templates/_shared/hooks-ts/task_create_capture.ts +48 -0
- package/dist/templates/_shared/hooks-ts/task_update_capture.ts +74 -0
- package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +83 -0
- package/dist/templates/_shared/lib-ts/CLAUDE.md +318 -0
- package/dist/templates/_shared/lib-ts/base/atomic-write.ts +138 -0
- package/dist/templates/_shared/lib-ts/base/constants.ts +306 -0
- package/dist/templates/_shared/lib-ts/base/git-state.ts +58 -0
- package/dist/templates/_shared/lib-ts/base/hook-utils.ts +439 -0
- package/dist/templates/_shared/lib-ts/base/inference.ts +252 -0
- package/dist/templates/_shared/lib-ts/base/logger.ts +250 -0
- package/dist/templates/_shared/lib-ts/base/state-io.ts +116 -0
- package/dist/templates/_shared/lib-ts/base/stop-words.ts +184 -0
- package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +162 -0
- package/dist/templates/_shared/lib-ts/base/utils.ts +184 -0
- package/dist/templates/_shared/lib-ts/context/context-formatter.ts +438 -0
- package/dist/templates/_shared/lib-ts/context/context-selector.ts +515 -0
- package/dist/templates/_shared/lib-ts/context/context-store.ts +707 -0
- package/dist/templates/_shared/lib-ts/context/plan-manager.ts +316 -0
- package/dist/templates/_shared/lib-ts/context/task-tracker.ts +185 -0
- package/dist/templates/_shared/lib-ts/handoff/document-generator.ts +216 -0
- package/dist/templates/_shared/lib-ts/handoff/handoff-reader.ts +159 -0
- package/dist/templates/_shared/lib-ts/package.json +21 -0
- package/dist/templates/_shared/lib-ts/templates/formatters.ts +104 -0
- package/dist/templates/_shared/{lib/templates/plan_context.py → lib-ts/templates/plan-context.ts} +14 -22
- package/dist/templates/_shared/lib-ts/tsconfig.json +13 -0
- package/dist/templates/_shared/lib-ts/types.ts +164 -0
- package/dist/templates/_shared/scripts/resolve_context.ts +24 -0
- package/dist/templates/_shared/scripts/resume_handoff.ts +321 -0
- package/dist/templates/_shared/scripts/save_handoff.ts +359 -0
- package/dist/templates/_shared/scripts/status_line.ts +733 -0
- package/dist/templates/cc-native/.claude/settings.json +175 -185
- package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +15 -17
- 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 -3
- 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/CLAUDE.md +109 -135
- package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.ts +119 -0
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +921 -0
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +61 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +157 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +709 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +199 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +124 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +57 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +83 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +80 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +119 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +162 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/nul +3 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +249 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +155 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/codex.ts +130 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/gemini.ts +106 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/index.ts +10 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/types.ts +23 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +243 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +18 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +310 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/verdict.ts +72 -0
- package/dist/templates/cc-native/_cc-native/plan-review.config.json +12 -16
- package/oclif.manifest.json +1 -1
- 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/_shared/hooks/__init__.py +0 -16
- package/dist/templates/_shared/hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/archive_plan.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/context_enforcer.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/context_monitor.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/file-suggestion.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/pre_compact.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/session_end.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/session_start.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/task_create_atomicity.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/task_create_capture.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/task_update_capture.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/archive_plan.py +0 -169
- package/dist/templates/_shared/hooks/context_monitor.py +0 -270
- package/dist/templates/_shared/hooks/file-suggestion.py +0 -215
- package/dist/templates/_shared/hooks/pre_compact.py +0 -104
- package/dist/templates/_shared/hooks/session_end.py +0 -173
- package/dist/templates/_shared/hooks/session_start.py +0 -206
- package/dist/templates/_shared/hooks/task_create_capture.py +0 -108
- package/dist/templates/_shared/hooks/task_update_capture.py +0 -145
- package/dist/templates/_shared/hooks/user_prompt_submit.py +0 -139
- package/dist/templates/_shared/lib/__init__.py +0 -1
- package/dist/templates/_shared/lib/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__init__.py +0 -65
- package/dist/templates/_shared/lib/base/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/atomic_write.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/constants.cpython-313.pyc +0 -0
- 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__/subprocess_utils.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/utils.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/atomic_write.py +0 -180
- package/dist/templates/_shared/lib/base/constants.py +0 -358
- package/dist/templates/_shared/lib/base/hook_utils.py +0 -341
- package/dist/templates/_shared/lib/base/inference.py +0 -318
- package/dist/templates/_shared/lib/base/logger.py +0 -291
- package/dist/templates/_shared/lib/base/stop_words.py +0 -213
- package/dist/templates/_shared/lib/base/subprocess_utils.py +0 -46
- package/dist/templates/_shared/lib/base/utils.py +0 -242
- package/dist/templates/_shared/lib/context/__init__.py +0 -102
- package/dist/templates/_shared/lib/context/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/cache.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_extractor.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_formatter.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_manager.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_selector.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_store.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/discovery.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/event_log.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/plan_archive.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/plan_manager.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/task_sync.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/task_tracker.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/context_formatter.py +0 -317
- package/dist/templates/_shared/lib/context/context_selector.py +0 -508
- package/dist/templates/_shared/lib/context/context_store.py +0 -653
- package/dist/templates/_shared/lib/context/plan_manager.py +0 -204
- package/dist/templates/_shared/lib/context/task_tracker.py +0 -188
- package/dist/templates/_shared/lib/handoff/__init__.py +0 -22
- package/dist/templates/_shared/lib/handoff/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/handoff/__pycache__/document_generator.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/handoff/document_generator.py +0 -278
- package/dist/templates/_shared/lib/templates/README.md +0 -206
- package/dist/templates/_shared/lib/templates/__init__.py +0 -36
- package/dist/templates/_shared/lib/templates/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/templates/__pycache__/formatters.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/templates/__pycache__/persona_questions.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/templates/__pycache__/plan_context.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/templates/formatters.py +0 -146
- package/dist/templates/_shared/scripts/__pycache__/save_handoff.cpython-313.pyc +0 -0
- package/dist/templates/_shared/scripts/__pycache__/status_line.cpython-313.pyc +0 -0
- package/dist/templates/_shared/scripts/save_handoff.py +0 -357
- package/dist/templates/_shared/scripts/status_line.py +0 -701
- package/dist/templates/cc-native/.claude/commands/cc-native/fresh-perspective.md +0 -8
- package/dist/templates/cc-native/.windsurf/workflows/cc-native/fresh-perspective.md +0 -8
- package/dist/templates/cc-native/MIGRATION.md +0 -86
- 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
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/add_plan_context.cpython-313.pyc +0 -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/__pycache__/mark_questions_asked.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_accepted.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_questions_early.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/suggest-fresh-perspective.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.py +0 -130
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.py +0 -869
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.py +0 -81
- package/dist/templates/cc-native/_cc-native/hooks/suggest-fresh-perspective.py +0 -340
- package/dist/templates/cc-native/_cc-native/lib/CLAUDE.md +0 -265
- package/dist/templates/cc-native/_cc-native/lib/__init__.py +0 -53
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/atomic_write.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/constants.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/debug.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/state.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/utils.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/constants.py +0 -45
- package/dist/templates/cc-native/_cc-native/lib/debug.py +0 -139
- package/dist/templates/cc-native/_cc-native/lib/orchestrator.py +0 -362
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__init__.py +0 -28
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/agent.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/base.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/codex.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/gemini.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/agent.py +0 -215
- package/dist/templates/cc-native/_cc-native/lib/reviewers/base.py +0 -88
- package/dist/templates/cc-native/_cc-native/lib/reviewers/codex.py +0 -124
- package/dist/templates/cc-native/_cc-native/lib/reviewers/gemini.py +0 -108
- package/dist/templates/cc-native/_cc-native/lib/state.py +0 -268
- package/dist/templates/cc-native/_cc-native/lib/utils.py +0 -1027
- package/dist/templates/cc-native/_cc-native/scripts/__pycache__/aggregate_agents.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/scripts/aggregate_agents.py +0 -168
- package/dist/templates/cc-native/_cc-native/workflows/fresh-perspective.md +0 -134
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CC-Native plan review type definitions.
|
|
3
|
+
* All interfaces, schemas, and prompt constants for the plan review engine.
|
|
4
|
+
* See cc-native-plan-review-spec.md §3
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Re-export shared types used by cc-native consumers
|
|
8
|
+
export type { ContextState, HookInput, HookOutput } from "../../_shared/lib-ts/types.js";
|
|
9
|
+
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Verdict & Decision Types
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
/** Verdict from a single reviewer */
|
|
15
|
+
export type Verdict = "error" | "fail" | "pass" | "skip" | "warn";
|
|
16
|
+
|
|
17
|
+
/** Decision after aggregating all verdicts */
|
|
18
|
+
export type ReviewDecision = "allow" | "deny";
|
|
19
|
+
|
|
20
|
+
/** Complexity level assigned by orchestrator */
|
|
21
|
+
export type ComplexityCategory = "high" | "medium" | "simple";
|
|
22
|
+
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Review Data Structures
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
/** A single issue found during review */
|
|
28
|
+
export interface ReviewIssue {
|
|
29
|
+
category: string;
|
|
30
|
+
issue: string;
|
|
31
|
+
severity: "high" | "low" | "medium";
|
|
32
|
+
suggested_fix: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Normalized review data from any reviewer */
|
|
36
|
+
export interface ReviewData {
|
|
37
|
+
issues: ReviewIssue[];
|
|
38
|
+
missing_sections: string[];
|
|
39
|
+
questions: string[];
|
|
40
|
+
summary: string;
|
|
41
|
+
summary_source: "default" | "reviewer";
|
|
42
|
+
verdict: Verdict;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Result from a single plan reviewer (Codex, Gemini, or Claude agent) */
|
|
46
|
+
export interface ReviewerResult {
|
|
47
|
+
data: Record<string, unknown>;
|
|
48
|
+
err: string;
|
|
49
|
+
name: string;
|
|
50
|
+
ok: boolean;
|
|
51
|
+
raw: string;
|
|
52
|
+
verdict: Verdict;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Result from the plan orchestrator */
|
|
56
|
+
export interface OrchestratorResult {
|
|
57
|
+
category: string;
|
|
58
|
+
complexity: ComplexityCategory;
|
|
59
|
+
error?: string;
|
|
60
|
+
reasoning: string;
|
|
61
|
+
selected_agents: string[];
|
|
62
|
+
skip_reason?: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Combined result from all review phases */
|
|
66
|
+
export interface CombinedReviewResult {
|
|
67
|
+
agents: Record<string, ReviewerResult>;
|
|
68
|
+
cli_reviewers: Record<string, ReviewerResult>;
|
|
69
|
+
orchestration: null | OrchestratorResult;
|
|
70
|
+
overall_verdict: Verdict;
|
|
71
|
+
plan_hash: string;
|
|
72
|
+
timestamp: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Result from verdict aggregation */
|
|
76
|
+
export interface ReviewDecisionResult {
|
|
77
|
+
reason: string; // "fail_veto" | "acceptable" | "no_signal"
|
|
78
|
+
score: number;
|
|
79
|
+
should_deny: boolean;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Agent & Orchestrator Configuration
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
|
|
86
|
+
/** Configuration for a Claude Code review agent */
|
|
87
|
+
export interface AgentConfig {
|
|
88
|
+
categories: string[];
|
|
89
|
+
description: string;
|
|
90
|
+
enabled: boolean;
|
|
91
|
+
focus: string;
|
|
92
|
+
model: string;
|
|
93
|
+
name: string;
|
|
94
|
+
system_prompt: string; // Markdown body content for --system-prompt
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Configuration for the plan orchestrator */
|
|
98
|
+
export interface OrchestratorConfig {
|
|
99
|
+
enabled: boolean;
|
|
100
|
+
model: string;
|
|
101
|
+
timeout: number;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
// State Interfaces
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
/** A single iteration history entry */
|
|
109
|
+
export interface IterationEntry {
|
|
110
|
+
hash: string;
|
|
111
|
+
timestamp: string;
|
|
112
|
+
verdict: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Iteration tracking state (stored adjacent to plan file) */
|
|
116
|
+
export interface IterationState {
|
|
117
|
+
complexity: string;
|
|
118
|
+
current: number;
|
|
119
|
+
graduated: string[];
|
|
120
|
+
history: IterationEntry[];
|
|
121
|
+
max: number;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** CC-native state stored in context state.json under cc_native key */
|
|
125
|
+
export interface CcNativeState {
|
|
126
|
+
[key: string]: unknown;
|
|
127
|
+
plan_review?: PlanReviewState;
|
|
128
|
+
questions_asked?: QuestionsAskedState;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Plan review state within cc_native */
|
|
132
|
+
export interface PlanReviewState {
|
|
133
|
+
decision: string;
|
|
134
|
+
iteration?: {
|
|
135
|
+
complexity: string;
|
|
136
|
+
current: number;
|
|
137
|
+
latest_verdict?: string;
|
|
138
|
+
max: number;
|
|
139
|
+
};
|
|
140
|
+
plan_hash: string;
|
|
141
|
+
reviewed_at: string;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Questions-asked tracking state */
|
|
145
|
+
export interface QuestionsAskedState {
|
|
146
|
+
asked: boolean;
|
|
147
|
+
asked_at: string;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
// Configuration
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
|
|
154
|
+
/** Display settings for review output formatting */
|
|
155
|
+
export interface DisplaySettings {
|
|
156
|
+
maxIssues: number;
|
|
157
|
+
maxMissingSections: number;
|
|
158
|
+
maxQuestions: number;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Full plan review configuration (from plan-review.config.json) */
|
|
162
|
+
export interface PlanReviewConfig {
|
|
163
|
+
[key: string]: unknown;
|
|
164
|
+
display?: Partial<DisplaySettings>;
|
|
165
|
+
planReview?: {
|
|
166
|
+
agentReview?: {
|
|
167
|
+
agentSelection?: Record<string, unknown>;
|
|
168
|
+
complexityCategories?: string[];
|
|
169
|
+
enabled?: boolean;
|
|
170
|
+
orchestrator?: { enabled?: boolean; model?: string; timeout?: number };
|
|
171
|
+
timeout?: number;
|
|
172
|
+
};
|
|
173
|
+
display?: Partial<DisplaySettings>;
|
|
174
|
+
earlyExitOnAllPass?: boolean;
|
|
175
|
+
enabled?: boolean;
|
|
176
|
+
reviewers?: {
|
|
177
|
+
codex?: { enabled?: boolean; model?: string; timeout?: number; };
|
|
178
|
+
gemini?: { enabled?: boolean; model?: string; timeout?: number; };
|
|
179
|
+
};
|
|
180
|
+
reviewIterations?: Record<string, number>;
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
// Reviewer Interface
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
|
|
188
|
+
/** Options passed to reviewer implementations */
|
|
189
|
+
export interface ReviewOptions {
|
|
190
|
+
context_path?: string;
|
|
191
|
+
session_name?: string;
|
|
192
|
+
timeout: number;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Interface all reviewers must implement */
|
|
196
|
+
export interface Reviewer {
|
|
197
|
+
review(
|
|
198
|
+
plan: string,
|
|
199
|
+
schema: Record<string, unknown>,
|
|
200
|
+
options: ReviewOptions,
|
|
201
|
+
): Promise<ReviewerResult>;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
// JSON Schemas
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
|
|
208
|
+
/** JSON schema for review structured output */
|
|
209
|
+
export const REVIEW_SCHEMA: Record<string, unknown> = {
|
|
210
|
+
type: "object",
|
|
211
|
+
properties: {
|
|
212
|
+
verdict: { type: "string", enum: ["pass", "warn", "fail"] },
|
|
213
|
+
summary: { type: "string", minLength: 20 },
|
|
214
|
+
issues: {
|
|
215
|
+
type: "array",
|
|
216
|
+
items: {
|
|
217
|
+
type: "object",
|
|
218
|
+
properties: {
|
|
219
|
+
severity: { type: "string", enum: ["high", "medium", "low"] },
|
|
220
|
+
category: { type: "string" },
|
|
221
|
+
issue: { type: "string" },
|
|
222
|
+
suggested_fix: { type: "string" },
|
|
223
|
+
},
|
|
224
|
+
required: ["severity", "category", "issue", "suggested_fix"],
|
|
225
|
+
additionalProperties: false,
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
missing_sections: { type: "array", items: { type: "string" } },
|
|
229
|
+
questions: { type: "array", items: { type: "string" } },
|
|
230
|
+
},
|
|
231
|
+
required: ["verdict", "summary", "issues", "missing_sections", "questions"],
|
|
232
|
+
additionalProperties: false,
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
/** JSON schema for orchestrator structured output */
|
|
236
|
+
export const ORCHESTRATOR_SCHEMA: Record<string, unknown> = {
|
|
237
|
+
type: "object",
|
|
238
|
+
properties: {
|
|
239
|
+
complexity: { type: "string", enum: ["simple", "medium", "high"] },
|
|
240
|
+
category: {
|
|
241
|
+
type: "string",
|
|
242
|
+
enum: [
|
|
243
|
+
"code",
|
|
244
|
+
"infrastructure",
|
|
245
|
+
"documentation",
|
|
246
|
+
"life",
|
|
247
|
+
"business",
|
|
248
|
+
"design",
|
|
249
|
+
"research",
|
|
250
|
+
],
|
|
251
|
+
},
|
|
252
|
+
selectedAgents: { type: "array", items: { type: "string" } },
|
|
253
|
+
reasoning: { type: "string" },
|
|
254
|
+
skipReason: { type: "string" },
|
|
255
|
+
},
|
|
256
|
+
required: ["complexity", "category", "selectedAgents", "reasoning"],
|
|
257
|
+
additionalProperties: false,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
// Prompt Constants
|
|
262
|
+
// ---------------------------------------------------------------------------
|
|
263
|
+
|
|
264
|
+
export const REVIEW_PROMPT_PREFIX = `You are a senior staff software engineer acting as a strict plan reviewer.
|
|
265
|
+
|
|
266
|
+
Review the PLAN below. Focus on:
|
|
267
|
+
- missing steps, unclear assumptions, edge cases
|
|
268
|
+
- security/privacy concerns
|
|
269
|
+
- testing/rollout/rollback completeness
|
|
270
|
+
- operational concerns (observability, failure modes)
|
|
271
|
+
`;
|
|
272
|
+
|
|
273
|
+
export const AGENT_REVIEW_PROMPT_PREFIX = `# SINGLE-TURN PLAN REVIEW
|
|
274
|
+
|
|
275
|
+
## CRITICAL: ONE TURN ONLY
|
|
276
|
+
You have exactly ONE response to complete this review. Do NOT attempt multi-step workflows, context queries, or phased analysis. Analyze the plan and output your review immediately.
|
|
277
|
+
|
|
278
|
+
## YOUR TASK
|
|
279
|
+
Review the plan below from your area of expertise. Then call StructuredOutput with your assessment.
|
|
280
|
+
|
|
281
|
+
## REQUIRED OUTPUT (all fields must have content)
|
|
282
|
+
Call StructuredOutput with:
|
|
283
|
+
- **verdict**: "pass" (no concerns), "warn" (some concerns), or "fail" (critical issues)
|
|
284
|
+
- **summary**: 2-3 sentences with your overall assessment and key findings (REQUIRED)
|
|
285
|
+
- **issues**: Array of concerns found. Format each as:
|
|
286
|
+
{"severity": "high/medium/low", "category": "...", "issue": "...", "suggested_fix": "..."}
|
|
287
|
+
- **missing_sections**: Topics the plan should address but doesn't
|
|
288
|
+
- **questions**: Things that need clarification before implementation
|
|
289
|
+
|
|
290
|
+
## IMPORTANT RULES
|
|
291
|
+
1. A "warn" verdict MUST include at least one issue explaining why
|
|
292
|
+
2. Summary MUST explain your reasoning, not just "looks good" or empty
|
|
293
|
+
3. Focus on your expertise area (architecture, security, performance, etc.)
|
|
294
|
+
4. Output StructuredOutput NOW - no other tools, no questions, no delays
|
|
295
|
+
`;
|
|
296
|
+
|
|
297
|
+
// ---------------------------------------------------------------------------
|
|
298
|
+
// Display Defaults
|
|
299
|
+
// ---------------------------------------------------------------------------
|
|
300
|
+
|
|
301
|
+
export const DEFAULT_DISPLAY: DisplaySettings = {
|
|
302
|
+
maxIssues: 12,
|
|
303
|
+
maxMissingSections: 12,
|
|
304
|
+
maxQuestions: 12,
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
export const DEFAULT_SANITIZATION = {
|
|
308
|
+
maxSessionIdLength: 32,
|
|
309
|
+
maxTitleLength: 50,
|
|
310
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure verdict aggregation logic.
|
|
3
|
+
* See cc-native-plan-review-spec.md §4.2
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ReviewDecisionResult, Verdict } from "./types.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Return the worst verdict from a list.
|
|
10
|
+
* Order: pass < warn < fail. skip→pass, error→warn.
|
|
11
|
+
*/
|
|
12
|
+
export function worstVerdict(verdicts: Verdict[]): Verdict {
|
|
13
|
+
const order: Record<Verdict, number> = {
|
|
14
|
+
pass: 0,
|
|
15
|
+
warn: 1,
|
|
16
|
+
fail: 2,
|
|
17
|
+
skip: 0,
|
|
18
|
+
error: 1,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
let worst: Verdict = "pass";
|
|
22
|
+
for (const v of verdicts) {
|
|
23
|
+
if ((order[v] ?? 1) > (order[worst] ?? 0)) {
|
|
24
|
+
worst = v;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Normalize error → warn
|
|
29
|
+
if (worst === "error") return "warn";
|
|
30
|
+
return worst;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Verdict aggregation: fail veto triggers a block.
|
|
35
|
+
*
|
|
36
|
+
* Priority order:
|
|
37
|
+
* 1. Fail Veto: Any fail → deny (ISO 61508 zero-tolerance)
|
|
38
|
+
* 2. Acceptable: warns are informational only
|
|
39
|
+
*
|
|
40
|
+
* Error exclusion: Detectors that produce no signal (error/skip) are excluded
|
|
41
|
+
* from the denominator.
|
|
42
|
+
*
|
|
43
|
+
* @param allVerdicts - List of verdict strings from all reviewers
|
|
44
|
+
* @returns ReviewDecisionResult with should_deny, reason, and score
|
|
45
|
+
*/
|
|
46
|
+
export function computeReviewDecision(
|
|
47
|
+
allVerdicts: Verdict[],
|
|
48
|
+
): ReviewDecisionResult {
|
|
49
|
+
// Exclude non-signal verdicts
|
|
50
|
+
const signalVerdicts = allVerdicts.filter(
|
|
51
|
+
(v) => v === "pass" || v === "warn" || v === "fail",
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (signalVerdicts.length === 0) {
|
|
55
|
+
return { should_deny: false, reason: "no_signal", score: 0.0 };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Fail blocks unconditionally
|
|
59
|
+
const failCount = signalVerdicts.filter((v) => v === "fail").length;
|
|
60
|
+
if (failCount > 0) {
|
|
61
|
+
return { should_deny: true, reason: "fail_veto", score: 1.0 };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Warn also blocks — reviewers flagged concerns worth addressing
|
|
65
|
+
const warnCount = signalVerdicts.filter((v) => v === "warn").length;
|
|
66
|
+
const warnRatio = warnCount / signalVerdicts.length;
|
|
67
|
+
if (warnCount > 0) {
|
|
68
|
+
return { should_deny: true, reason: "warn_block", score: warnRatio };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { should_deny: false, reason: "acceptable", score: 0.0 };
|
|
72
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"reviewers": {
|
|
5
5
|
"codex": {
|
|
6
6
|
"enabled": true,
|
|
7
|
-
"model": "
|
|
7
|
+
"model": "gpt-5.1-codex-mini",
|
|
8
8
|
"timeout": 120
|
|
9
9
|
},
|
|
10
10
|
"gemini": {
|
|
@@ -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": {
|
|
@@ -67,13 +71,5 @@
|
|
|
67
71
|
"planContext": {
|
|
68
72
|
"enabled": true,
|
|
69
73
|
"offerClarifyingQuestions": true
|
|
70
|
-
},
|
|
71
|
-
"stuckDetection": {
|
|
72
|
-
"enabled": true,
|
|
73
|
-
"errorThreshold": 3,
|
|
74
|
-
"fileEditThreshold": 4,
|
|
75
|
-
"testFailureThreshold": 3,
|
|
76
|
-
"cooldown": 10,
|
|
77
|
-
"maxSuggestions": 3
|
|
78
74
|
}
|
|
79
75
|
}
|
package/oclif.manifest.json
CHANGED
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,16 +0,0 @@
|
|
|
1
|
-
"""Shared hooks for AIW CLI templates.
|
|
2
|
-
|
|
3
|
-
These hooks integrate with Claude Code's hook system to provide:
|
|
4
|
-
- UserPromptSubmit: Context enforcement (ensures work happens in tracked context)
|
|
5
|
-
- PostToolUse: Context monitoring and handoff warnings
|
|
6
|
-
- ExitPlanMode: Plan archival to context
|
|
7
|
-
|
|
8
|
-
Hooks read JSON input from stdin and output instructions to stdout.
|
|
9
|
-
|
|
10
|
-
Available hooks:
|
|
11
|
-
- user_prompt_submit.py: Runs on user prompt, enforces context tracking
|
|
12
|
-
- context_monitor.py: Runs on PostToolUse, monitors context and warns when low
|
|
13
|
-
- archive_plan.py: Runs on ExitPlanMode, archives plan to context
|
|
14
|
-
- task_create_capture.py: Runs on TaskCreate, captures task events
|
|
15
|
-
- task_update_capture.py: Runs on TaskUpdate, captures task updates
|
|
16
|
-
"""
|
|
Binary file
|