aiwcli 0.9.4 → 0.9.6
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/templates/_shared/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/user_prompt_submit.py +1 -1
- 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/stop_words.py +32 -0
- package/dist/templates/_shared/lib/base/utils.py +5 -20
- package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/ACCESSIBILITY-TESTER.md +0 -1
- package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +56 -0
- package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/CODE-REVIEWER.md +0 -1
- package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/CONTEXT-EXTRACTOR.md +0 -1
- package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/PENETRATION-TESTER.md +0 -1
- package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/PERFORMANCE-ENGINEER.md +0 -1
- package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/PLAN-ORCHESTRATOR.md +0 -1
- package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/TRADE-OFF-ILLUMINATOR.md +0 -1
- 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 +10 -11
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/orchestrator.py +36 -18
- 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/agent.py +11 -9
- package/dist/templates/cc-native/_cc-native/lib/reviewers/base.py +1 -2
- package/dist/templates/cc-native/_cc-native/plan-review.config.json +2 -4
- 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 +25 -8
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/ARCHITECT-REVIEWER.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/ASSUMPTION-CHAIN-TRACER.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/CLARITY-AUDITOR.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/COMPLETENESS-CHECKER.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/DEVILS-ADVOCATE.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/DOCUMENTATION-REVIEWER.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/FEASIBILITY-ANALYST.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/FRESH-PERSPECTIVE.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/HANDOFF-READINESS.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/HIDDEN-COMPLEXITY-DETECTOR.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/INCENTIVE-MAPPER.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/PRECEDENT-FINDER.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/REVERSIBILITY-ANALYST.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/RISK-ASSESSOR.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/SECOND-ORDER-ANALYST.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/SIMPLICITY-GUARDIAN.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/SKEPTIC.md +0 -0
- /package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/STAKEHOLDER-ADVOCATE.md +0 -0
|
Binary file
|
|
@@ -103,7 +103,7 @@ def _update_in_flight_status(context_id: str, hook_input: dict, project_root: Pa
|
|
|
103
103
|
elif permission_mode != "plan":
|
|
104
104
|
# Any non-plan permission mode transitions pending/planning to implementing
|
|
105
105
|
# This includes "default" (after /clear) and "acceptEdits"/"bypassPermissions"
|
|
106
|
-
if current_mode in ["pending_implementation", "planning"]:
|
|
106
|
+
if current_mode in ["pending_implementation", "planning", "none"]:
|
|
107
107
|
update_plan_status(context_id, "implementing", project_root=project_root)
|
|
108
108
|
eprint(f"[user_prompt_submit] Set status to 'implementing' (permission_mode={permission_mode})")
|
|
109
109
|
|
|
Binary file
|
|
Binary file
|
|
@@ -155,4 +155,36 @@ STOP_WORDS = {
|
|
|
155
155
|
'part', 'parts', 'point', 'points',
|
|
156
156
|
'time', 'times', 'next', 'last', 'end',
|
|
157
157
|
'set', 'list', 'group', 'item', 'items',
|
|
158
|
+
|
|
159
|
+
# ========================================================================
|
|
160
|
+
# PROGRAMMING KEYWORDS (code tokens that leak from pasted code)
|
|
161
|
+
# ========================================================================
|
|
162
|
+
'self', 'def', 'return', 'import', 'true', 'false', 'none', 'str',
|
|
163
|
+
'const', 'async', 'class', 'assert', 'except', 'dict', 'len', 'args',
|
|
164
|
+
'sys', 'eprint', 'elif', 'lambda', 'yield', 'pass',
|
|
165
|
+
|
|
166
|
+
# ========================================================================
|
|
167
|
+
# GENERIC ADJECTIVES (non-specific modifiers)
|
|
168
|
+
# ========================================================================
|
|
169
|
+
'high', 'low', 'important', 'critical', 'optional', 'manual',
|
|
170
|
+
'real', 'empty', 'stable', 'active', 'proper', 'correct',
|
|
171
|
+
'basic', 'main', 'primary', 'secondary', 'general', 'overall',
|
|
172
|
+
|
|
173
|
+
# ========================================================================
|
|
174
|
+
# GENERIC TECHNICAL NOUNS (common but non-specific)
|
|
175
|
+
# ========================================================================
|
|
176
|
+
'information', 'format', 'status', 'method', 'purpose', 'result',
|
|
177
|
+
'source', 'value', 'option', 'options', 'feature', 'features', 'issue',
|
|
178
|
+
'process', 'version', 'mode', 'state',
|
|
179
|
+
|
|
180
|
+
# ========================================================================
|
|
181
|
+
# DOCUMENT/CODE STRUCTURE (generic structural terms)
|
|
182
|
+
# ========================================================================
|
|
183
|
+
'section', 'lines', 'line', 'folder', 'directory', 'index',
|
|
184
|
+
'level', 'block', 'chunk', 'region', 'header', 'footer',
|
|
185
|
+
|
|
186
|
+
# ========================================================================
|
|
187
|
+
# FRAGMENT WORDS (artifacts from contractions/tokenization)
|
|
188
|
+
# ========================================================================
|
|
189
|
+
're', 'pl', 'aiw', 've', 'll', 'doesn', 't', 's',
|
|
158
190
|
}
|
|
@@ -138,8 +138,7 @@ def generate_context_id(summary: str, existing_ids: Optional[set] = None) -> str
|
|
|
138
138
|
"""
|
|
139
139
|
Generate a context ID from a summary string.
|
|
140
140
|
|
|
141
|
-
|
|
142
|
-
Falls back to truncate-and-slugify if inference fails.
|
|
141
|
+
Filters stop words from the summary and slugifies the result.
|
|
143
142
|
|
|
144
143
|
Args:
|
|
145
144
|
summary: Context summary text
|
|
@@ -151,24 +150,10 @@ def generate_context_id(summary: str, existing_ids: Optional[set] = None) -> str
|
|
|
151
150
|
if not summary or not summary.strip():
|
|
152
151
|
base_id = "context"
|
|
153
152
|
else:
|
|
154
|
-
#
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
semantic = generate_semantic_summary(summary)
|
|
159
|
-
if semantic:
|
|
160
|
-
# Slugify the semantic summary (word limit already applied in inference)
|
|
161
|
-
base_id = sanitize_title(semantic, max_len=100)
|
|
162
|
-
eprint(f"[utils] Semantic context ID: {base_id}")
|
|
163
|
-
except Exception as e:
|
|
164
|
-
eprint(f"[utils] Inference failed, using fallback: {e}")
|
|
165
|
-
|
|
166
|
-
# Fallback to old method if inference failed
|
|
167
|
-
if not base_id:
|
|
168
|
-
# Fallback: use stop word filter, limit to 12 words
|
|
169
|
-
from .stop_words import STOP_WORDS
|
|
170
|
-
words = [w for w in summary.lower().split() if w not in STOP_WORDS and len(w) > 1][:12]
|
|
171
|
-
base_id = sanitize_title(' '.join(words), max_len=100)
|
|
153
|
+
# Use stop word filter, limit to 12 words
|
|
154
|
+
from .stop_words import STOP_WORDS
|
|
155
|
+
words = [w for w in summary.lower().split() if w not in STOP_WORDS and len(w) > 1][:12]
|
|
156
|
+
base_id = sanitize_title(' '.join(words), max_len=100)
|
|
172
157
|
|
|
173
158
|
if not existing_ids:
|
|
174
159
|
return base_id
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# CC-Native Plan Review Agents
|
|
2
|
+
|
|
3
|
+
Agent persona definitions for single-turn plan review.
|
|
4
|
+
|
|
5
|
+
## System Prompt vs Agent Flag
|
|
6
|
+
|
|
7
|
+
**Decision:** Use `--system-prompt` with markdown body content instead of `--agent <name>`
|
|
8
|
+
|
|
9
|
+
**Rationale:**
|
|
10
|
+
- Claude Code's `--agent` flag invokes built-in agents designed for multi-turn agentic workflows with tool access
|
|
11
|
+
- Plan review needs single-turn text analysis: read plan, output structured JSON
|
|
12
|
+
- The `--agent` flag ignores our custom markdown content entirely - it loads Claude Code's built-in agent definitions
|
|
13
|
+
- Using `--system-prompt` lets us inject the full persona (expertise, review approach, output requirements) directly
|
|
14
|
+
- Result: faster execution, no tool overhead, and our rich agent descriptions actually get used
|
|
15
|
+
|
|
16
|
+
**Constraint:** If you switch back to `--agent`, the elaborate persona content in these markdown files will be ignored. The reviews will use Claude Code's generic agent behavior instead of our specialized reviewers.
|
|
17
|
+
|
|
18
|
+
## File Structure
|
|
19
|
+
|
|
20
|
+
Each agent file has:
|
|
21
|
+
- **Frontmatter (YAML):** name, model, focus, categories, enabled
|
|
22
|
+
- **Body (Markdown):** Full persona content → becomes `system_prompt` for `--system-prompt` flag
|
|
23
|
+
|
|
24
|
+
The `aggregate_agents.py` script extracts both parts. The body becomes `AgentConfig.system_prompt`.
|
|
25
|
+
|
|
26
|
+
## --setting-sources "" Requirement
|
|
27
|
+
|
|
28
|
+
**Decision:** Use `--setting-sources ""` to disable user/project settings loading
|
|
29
|
+
|
|
30
|
+
**Rationale:**
|
|
31
|
+
- Without this flag, Claude Code loads user settings (~43k cached tokens of PAI context)
|
|
32
|
+
- The PAI Algorithm instructions override the agent's system prompt behavior
|
|
33
|
+
- Model tries to follow PAI format instead of calling StructuredOutput directly
|
|
34
|
+
- Result: 6+ turns, 30+ seconds, often no structured output
|
|
35
|
+
|
|
36
|
+
**Constraint:** If you remove `--setting-sources ""`, agent reviews will be slow and unreliable due to PAI context interference.
|
|
37
|
+
|
|
38
|
+
## --max-turns 3 Requirement
|
|
39
|
+
|
|
40
|
+
**Decision:** Use `--max-turns 3` with agent invocations
|
|
41
|
+
|
|
42
|
+
**Rationale:**
|
|
43
|
+
- `--max-turns 1` is too restrictive - the model needs turn 1 to call StructuredOutput, turn 2 for the tool result
|
|
44
|
+
- `--max-turns 2` works but leaves no buffer for edge cases
|
|
45
|
+
- `--max-turns 3` gives safety margin while still preventing runaway multi-turn behavior
|
|
46
|
+
- With these settings, reviews complete in ~5-10 seconds
|
|
47
|
+
|
|
48
|
+
**Constraint:** The agent markdown files MUST contain clear instructions to "call StructuredOutput IMMEDIATELY" and "do NOT use any other tools". Without these instructions, the model will try to use its turns for file operations instead of outputting the review.
|
|
49
|
+
|
|
50
|
+
## enabled: false Convention
|
|
51
|
+
|
|
52
|
+
**Decision:** Set `enabled: false` in frontmatter for all plan review agents
|
|
53
|
+
|
|
54
|
+
**Rationale:** The `enabled` field controls Claude Code's auto-suggestion feature (showing agents in command palette). For plan review agents, we don't want them appearing as general-purpose agents - they're invoked programmatically by the hook. Setting `enabled: false` hides them from auto-suggestion while still allowing the hook to use them.
|
|
55
|
+
|
|
56
|
+
**Constraint:** Don't set `enabled: true` unless you want the agent to appear in Claude Code's agent picker for general use.
|
package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/CONTEXT-EXTRACTOR.md
RENAMED
|
@@ -9,7 +9,6 @@ categories:
|
|
|
9
9
|
- infrastructure
|
|
10
10
|
- design
|
|
11
11
|
- research
|
|
12
|
-
tools: ""
|
|
13
12
|
---
|
|
14
13
|
|
|
15
14
|
You are a Context Extractor agent that prepares abstracted problem context for the Fresh Perspective agent. Your job is to distill a conversation into its essential elements while **stripping away implementation details** that could bias fresh thinking.
|
|
@@ -12,7 +12,6 @@ categories:
|
|
|
12
12
|
- research
|
|
13
13
|
- life
|
|
14
14
|
- business
|
|
15
|
-
tools: Read, Glob, Grep
|
|
16
15
|
---
|
|
17
16
|
|
|
18
17
|
You are a trade-off illuminator who makes hidden costs explicit. While other agents ask "Is this approach good?", you ask "What are you giving up to get this?" Your focus is exposing the price of every decision—the capabilities sacrificed, the stakeholders who lose, the futures foreclosed.
|
package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-plan-review.cpython-313.pyc
CHANGED
|
Binary file
|
|
@@ -118,7 +118,6 @@ DEFAULT_ORCHESTRATOR: Dict[str, Any] = {
|
|
|
118
118
|
"enabled": True,
|
|
119
119
|
"model": "haiku",
|
|
120
120
|
"timeout": 30,
|
|
121
|
-
"maxTurns": 3,
|
|
122
121
|
}
|
|
123
122
|
|
|
124
123
|
DEFAULT_AGENT_MODEL: str = "sonnet"
|
|
@@ -331,10 +330,9 @@ def load_settings(proj_dir: Path) -> Dict[str, Any]:
|
|
|
331
330
|
"agentReview": {
|
|
332
331
|
"enabled": True,
|
|
333
332
|
"orchestrator": DEFAULT_ORCHESTRATOR.copy(),
|
|
334
|
-
"timeout":
|
|
333
|
+
"timeout": 180,
|
|
335
334
|
"blockOnFail": True,
|
|
336
335
|
"legacyMode": False,
|
|
337
|
-
"maxTurns": 3,
|
|
338
336
|
"display": DEFAULT_DISPLAY.copy(),
|
|
339
337
|
"agentSelection": DEFAULT_AGENT_SELECTION.copy(),
|
|
340
338
|
"agentDefaults": {"model": DEFAULT_AGENT_MODEL},
|
|
@@ -383,9 +381,13 @@ def load_settings(proj_dir: Path) -> Dict[str, Any]:
|
|
|
383
381
|
|
|
384
382
|
|
|
385
383
|
def load_agent_library(proj_dir: Path, settings: Optional[Dict[str, Any]] = None) -> List[AgentConfig]:
|
|
386
|
-
"""Load agent library by auto-detecting from frontmatter.
|
|
387
|
-
|
|
388
|
-
|
|
384
|
+
"""Load agent library by auto-detecting from frontmatter.
|
|
385
|
+
|
|
386
|
+
Agents are loaded from _cc-native/agents/ directory. The markdown body
|
|
387
|
+
of each agent file becomes the system_prompt for --system-prompt invocation.
|
|
388
|
+
"""
|
|
389
|
+
# aggregate_agents now defaults to _cc-native/agents/ relative to the script
|
|
390
|
+
agents_data = aggregate_agents()
|
|
389
391
|
|
|
390
392
|
default_model = DEFAULT_AGENT_MODEL
|
|
391
393
|
if settings:
|
|
@@ -415,7 +417,7 @@ def load_agent_library(proj_dir: Path, settings: Optional[Dict[str, Any]] = None
|
|
|
415
417
|
enabled=a.get("enabled", True),
|
|
416
418
|
categories=a.get("categories", ["code"]),
|
|
417
419
|
description=a.get("description", ""),
|
|
418
|
-
|
|
420
|
+
system_prompt=a.get("system_prompt", ""),
|
|
419
421
|
))
|
|
420
422
|
|
|
421
423
|
return agents
|
|
@@ -539,7 +541,6 @@ def main() -> int:
|
|
|
539
541
|
enabled=orch_settings.get("enabled", True) and agent_review_enabled,
|
|
540
542
|
model=orch_settings.get("model", "haiku"),
|
|
541
543
|
timeout=orch_settings.get("timeout", 30),
|
|
542
|
-
max_turns=orch_settings.get("maxTurns", 3),
|
|
543
544
|
)
|
|
544
545
|
|
|
545
546
|
eprint(f"[cc-native-plan-review] Codex enabled: {codex_enabled}, Gemini enabled: {gemini_enabled}")
|
|
@@ -642,7 +643,6 @@ def main() -> int:
|
|
|
642
643
|
# PHASE 3: Run selected agents in parallel
|
|
643
644
|
if selected_agents:
|
|
644
645
|
eprint("[cc-native-plan-review] === PHASE 3: Agent Reviews ===")
|
|
645
|
-
max_turns = agent_settings.get("maxTurns", 3)
|
|
646
646
|
max_parallel = agent_settings.get("maxParallelAgents", 0) # 0 = unlimited
|
|
647
647
|
num_workers = len(selected_agents) if max_parallel <= 0 else min(max_parallel, len(selected_agents))
|
|
648
648
|
eprint(f"[cc-native-plan-review] Launching {len(selected_agents)} agents in parallel (workers={num_workers})")
|
|
@@ -651,13 +651,12 @@ def main() -> int:
|
|
|
651
651
|
debug_log(context_path, session_id, "hook", "agent_review_start", {
|
|
652
652
|
"agents": [a.name for a in selected_agents],
|
|
653
653
|
"timeout": timeout,
|
|
654
|
-
"max_turns": max_turns,
|
|
655
654
|
"complexity": detected_complexity,
|
|
656
655
|
})
|
|
657
656
|
|
|
658
657
|
with ThreadPoolExecutor(max_workers=num_workers) as executor:
|
|
659
658
|
futures = {
|
|
660
|
-
executor.submit(run_agent_review, plan, agent, REVIEW_SCHEMA, timeout,
|
|
659
|
+
executor.submit(run_agent_review, plan, agent, REVIEW_SCHEMA, timeout, context_path, session_id): agent
|
|
661
660
|
for agent in selected_agents
|
|
662
661
|
}
|
|
663
662
|
for future in as_completed(futures):
|
|
Binary file
|
|
@@ -129,7 +129,7 @@ def run_orchestrator(
|
|
|
129
129
|
Args:
|
|
130
130
|
plan: The plan content to analyze
|
|
131
131
|
agent_library: List of available agents
|
|
132
|
-
config: Orchestrator configuration (model, timeout
|
|
132
|
+
config: Orchestrator configuration (model, timeout)
|
|
133
133
|
settings: Agent review settings (agentSelection, complexityCategories)
|
|
134
134
|
|
|
135
135
|
Returns:
|
|
@@ -154,9 +154,11 @@ def run_orchestrator(
|
|
|
154
154
|
|
|
155
155
|
eprint(f"[orchestrator] Found Claude CLI at: {claude_path}")
|
|
156
156
|
|
|
157
|
-
# Build agent list for prompt
|
|
157
|
+
# Build agent list for prompt with rich descriptions
|
|
158
158
|
agent_list = "\n".join([
|
|
159
|
-
f"- {a.name}
|
|
159
|
+
f"- {a.name} [{', '.join(a.categories)}]\n"
|
|
160
|
+
f" Focus: {a.focus}\n"
|
|
161
|
+
f" Expertise: {a.description}"
|
|
160
162
|
for a in agent_library if a.enabled
|
|
161
163
|
])
|
|
162
164
|
category_list = "/".join(categories)
|
|
@@ -164,43 +166,48 @@ def run_orchestrator(
|
|
|
164
166
|
medium_range = f"{selection.get('medium', {}).get('min', 1)}-{selection.get('medium', {}).get('max', 2)}"
|
|
165
167
|
high_range = f"{selection.get('high', {}).get('min', 2)}-{selection.get('high', {}).get('max', 4)}"
|
|
166
168
|
|
|
167
|
-
|
|
169
|
+
# System prompt with orchestrator instructions
|
|
170
|
+
system_prompt = """You are a plan orchestrator for code review. Your job is to analyze plans and select appropriate reviewer agents.
|
|
168
171
|
|
|
169
|
-
You
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
172
|
+
You MUST call StructuredOutput immediately with your analysis. Do NOT ask questions or use any other tools.
|
|
173
|
+
|
|
174
|
+
When selecting agents:
|
|
175
|
+
- Match agent expertise to plan requirements
|
|
176
|
+
- Consider what each agent specializes in
|
|
177
|
+
- Only select agents whose categories match the plan category
|
|
178
|
+
- Fewer agents for simple plans, more for complex plans"""
|
|
179
|
+
|
|
180
|
+
# User prompt with plan and agent list
|
|
181
|
+
prompt = f"""Analyze this plan and select appropriate reviewer agents.
|
|
173
182
|
|
|
174
183
|
Available agents:
|
|
175
184
|
{agent_list}
|
|
176
185
|
|
|
177
|
-
|
|
178
|
-
- simple complexity = {simple_range} agents
|
|
186
|
+
Selection rules:
|
|
187
|
+
- simple complexity = {simple_range} agents
|
|
179
188
|
- medium complexity = {medium_range} agents
|
|
180
189
|
- high complexity = {high_range} agents
|
|
181
|
-
- Only select agents whose categories match the plan category
|
|
190
|
+
- Only select agents whose categories match the plan category ({category_list})
|
|
182
191
|
- Non-technical plans (life, business) typically need 0 code-focused agents
|
|
183
192
|
|
|
184
|
-
Analyze and call StructuredOutput with your decision now.
|
|
185
|
-
|
|
186
193
|
PLAN:
|
|
187
194
|
<<<
|
|
188
195
|
{plan}
|
|
189
196
|
>>>
|
|
190
|
-
|
|
197
|
+
|
|
198
|
+
Call StructuredOutput now with: complexity, category, selectedAgents, reasoning"""
|
|
191
199
|
|
|
192
200
|
schema_json = json.dumps(ORCHESTRATOR_SCHEMA, ensure_ascii=False)
|
|
193
201
|
|
|
194
202
|
cmd_args = [
|
|
195
203
|
claude_path,
|
|
196
204
|
"-p", # Enable print mode to read prompt from stdin
|
|
197
|
-
"--agent", "plan-orchestrator",
|
|
198
205
|
"--model", config.model,
|
|
199
|
-
"--permission-mode", "bypassPermissions",
|
|
200
206
|
"--output-format", "json",
|
|
201
|
-
"--max-turns", str(config.max_turns),
|
|
202
207
|
"--json-schema", schema_json,
|
|
203
|
-
"--
|
|
208
|
+
"--max-turns", "3", # Single-turn with buffer for tool call + result
|
|
209
|
+
"--setting-sources", "", # Disable PAI context interference
|
|
210
|
+
"--system-prompt", system_prompt,
|
|
204
211
|
]
|
|
205
212
|
|
|
206
213
|
eprint(f"[orchestrator] Running with model: {config.model}, timeout: {config.timeout}s")
|
|
@@ -245,6 +252,17 @@ PLAN:
|
|
|
245
252
|
eprint(f"[orchestrator] stderr: {p.stderr[:300]}")
|
|
246
253
|
|
|
247
254
|
obj = _parse_claude_output(raw)
|
|
255
|
+
|
|
256
|
+
# Debug logging to diagnose empty selectedAgents issue
|
|
257
|
+
eprint(f"[orchestrator:debug] Raw output length: {len(raw)} chars")
|
|
258
|
+
if raw:
|
|
259
|
+
eprint(f"[orchestrator:debug] Raw output (first 500 chars): {raw[:500]}")
|
|
260
|
+
eprint(f"[orchestrator:debug] Parsed obj: {obj}")
|
|
261
|
+
if obj:
|
|
262
|
+
eprint(f"[orchestrator:debug] obj keys: {list(obj.keys())}")
|
|
263
|
+
eprint(f"[orchestrator:debug] selectedAgents value: {obj.get('selectedAgents', 'MISSING')}")
|
|
264
|
+
eprint(f"[orchestrator:debug] reasoning value: {obj.get('reasoning', 'MISSING')}")
|
|
265
|
+
|
|
248
266
|
if not obj:
|
|
249
267
|
eprint("[orchestrator] Failed to parse output, falling back to medium complexity")
|
|
250
268
|
return OrchestratorResult(
|
|
Binary file
|
|
Binary file
|
|
@@ -81,7 +81,6 @@ def run_agent_review(
|
|
|
81
81
|
agent: AgentConfig,
|
|
82
82
|
schema: Dict[str, Any],
|
|
83
83
|
timeout: int,
|
|
84
|
-
max_turns: int = 3,
|
|
85
84
|
context_path: Optional[Path] = None,
|
|
86
85
|
session_name: str = "unknown",
|
|
87
86
|
) -> ReviewerResult:
|
|
@@ -92,7 +91,6 @@ def run_agent_review(
|
|
|
92
91
|
agent: Agent configuration (name, model, etc.)
|
|
93
92
|
schema: JSON schema for the review output
|
|
94
93
|
timeout: Timeout in seconds
|
|
95
|
-
max_turns: Maximum agent turns
|
|
96
94
|
context_path: Optional path to context folder for debug logging
|
|
97
95
|
session_name: Session name for debug logging
|
|
98
96
|
|
|
@@ -113,7 +111,8 @@ def run_agent_review(
|
|
|
113
111
|
|
|
114
112
|
eprint(f"[{agent.name}] Found Claude CLI at: {claude_path}")
|
|
115
113
|
|
|
116
|
-
prompt
|
|
114
|
+
# User prompt contains just the task and plan
|
|
115
|
+
prompt = f"""Review the plan below and provide your assessment using StructuredOutput.
|
|
117
116
|
|
|
118
117
|
PLAN:
|
|
119
118
|
<<<
|
|
@@ -122,19 +121,23 @@ PLAN:
|
|
|
122
121
|
"""
|
|
123
122
|
|
|
124
123
|
schema_json = json.dumps(schema, ensure_ascii=False)
|
|
124
|
+
|
|
125
|
+
# Build command args - use --system-prompt with the markdown body as persona
|
|
125
126
|
cmd_args = [
|
|
126
127
|
claude_path,
|
|
127
128
|
"-p", # Enable print mode to read prompt from stdin
|
|
128
|
-
"--agent", agent.name,
|
|
129
129
|
"--model", agent.model,
|
|
130
|
-
"--permission-mode", "plan",
|
|
131
130
|
"--output-format", "json",
|
|
132
|
-
"--max-turns", str(max_turns),
|
|
133
131
|
"--json-schema", schema_json,
|
|
134
|
-
"--
|
|
132
|
+
"--max-turns", "3", # Allow buffer for tool call + result (usually completes in 2)
|
|
133
|
+
"--setting-sources", "", # Disable user/project settings to avoid PAI context interference
|
|
135
134
|
]
|
|
136
135
|
|
|
137
|
-
|
|
136
|
+
# Add system prompt if available (the markdown body with full persona)
|
|
137
|
+
if agent.system_prompt:
|
|
138
|
+
cmd_args.extend(["--system-prompt", agent.system_prompt])
|
|
139
|
+
|
|
140
|
+
eprint(f"[{agent.name}] Running with model: {agent.model}, timeout: {timeout}s")
|
|
138
141
|
|
|
139
142
|
# Get environment for internal subprocess (bypasses hooks)
|
|
140
143
|
env = get_internal_subprocess_env()
|
|
@@ -176,7 +179,6 @@ PLAN:
|
|
|
176
179
|
"stderr_len": len(err),
|
|
177
180
|
"model": agent.model,
|
|
178
181
|
"timeout": timeout,
|
|
179
|
-
"max_turns": max_turns,
|
|
180
182
|
})
|
|
181
183
|
|
|
182
184
|
if raw:
|
|
@@ -39,7 +39,7 @@ class AgentConfig:
|
|
|
39
39
|
enabled: bool = True
|
|
40
40
|
categories: List[str] = field(default_factory=lambda: ["code"])
|
|
41
41
|
description: str = ""
|
|
42
|
-
|
|
42
|
+
system_prompt: str = "" # Markdown body content for --system-prompt
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
@dataclass
|
|
@@ -48,7 +48,6 @@ class OrchestratorConfig:
|
|
|
48
48
|
enabled: bool = True
|
|
49
49
|
model: str = "haiku"
|
|
50
50
|
timeout: int = 30
|
|
51
|
-
max_turns: int = 3
|
|
52
51
|
|
|
53
52
|
|
|
54
53
|
# ---------------------------
|
|
@@ -22,14 +22,12 @@
|
|
|
22
22
|
},
|
|
23
23
|
"agentReview": {
|
|
24
24
|
"enabled": true,
|
|
25
|
-
"timeout":
|
|
25
|
+
"timeout": 180,
|
|
26
26
|
"blockOnFail": true,
|
|
27
|
-
"maxTurns": 2,
|
|
28
27
|
"orchestrator": {
|
|
29
28
|
"enabled": true,
|
|
30
29
|
"model": "haiku",
|
|
31
|
-
"timeout": 30
|
|
32
|
-
"maxTurns": 6
|
|
30
|
+
"timeout": 30
|
|
33
31
|
},
|
|
34
32
|
"legacyMode": false,
|
|
35
33
|
"mandatoryAgents": ["handoff-readiness", "clarity-auditor", "skeptic"],
|
package/dist/templates/cc-native/_cc-native/scripts/__pycache__/aggregate_agents.cpython-313.pyc
CHANGED
|
Binary file
|
|
@@ -93,16 +93,31 @@ def extract_frontmatter(content: str) -> dict[str, Any] | None:
|
|
|
93
93
|
return None
|
|
94
94
|
|
|
95
95
|
|
|
96
|
+
def extract_body(content: str) -> str:
|
|
97
|
+
"""Extract markdown body (after frontmatter) from content.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
content: Raw markdown file content
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Markdown body content (everything after the closing ---)
|
|
104
|
+
"""
|
|
105
|
+
match = re.match(r'^---\s*\n.*?\n---\s*\n(.*)$', content, re.DOTALL)
|
|
106
|
+
if match:
|
|
107
|
+
return match.group(1).strip()
|
|
108
|
+
return content.strip()
|
|
109
|
+
|
|
110
|
+
|
|
96
111
|
def aggregate_agents(agents_dir: Path | None = None) -> list[dict[str, Any]]:
|
|
97
112
|
"""Read all agent files and return aggregated metadata.
|
|
98
|
-
|
|
113
|
+
|
|
99
114
|
Scans the agents directory for .md files, extracts frontmatter from each,
|
|
100
115
|
and returns a list of agent configurations.
|
|
101
|
-
|
|
116
|
+
|
|
102
117
|
Args:
|
|
103
118
|
agents_dir: Path to agents directory. If None, uses default
|
|
104
|
-
|
|
105
|
-
|
|
119
|
+
_cc-native/agents/ relative to this script.
|
|
120
|
+
|
|
106
121
|
Returns:
|
|
107
122
|
List of agent configuration dicts with fields:
|
|
108
123
|
- name: Agent identifier (lowercase)
|
|
@@ -111,14 +126,14 @@ def aggregate_agents(agents_dir: Path | None = None) -> list[dict[str, Any]]:
|
|
|
111
126
|
- focus: Brief focus for orchestrator
|
|
112
127
|
- enabled: Whether agent is available
|
|
113
128
|
- categories: Work categories for filtering
|
|
114
|
-
-
|
|
129
|
+
- system_prompt: Full markdown body (persona content)
|
|
115
130
|
"""
|
|
116
131
|
if agents_dir is None:
|
|
117
|
-
# Default to
|
|
132
|
+
# Default to _cc-native/agents/ relative to this script's location
|
|
118
133
|
# Script is at: _cc-native/scripts/aggregate_agents.py
|
|
119
|
-
# Agents are at:
|
|
134
|
+
# Agents are at: _cc-native/agents/
|
|
120
135
|
script_dir = Path(__file__).parent
|
|
121
|
-
agents_dir = script_dir.parent
|
|
136
|
+
agents_dir = script_dir.parent / "agents"
|
|
122
137
|
|
|
123
138
|
agents = []
|
|
124
139
|
|
|
@@ -135,6 +150,8 @@ def aggregate_agents(agents_dir: Path | None = None) -> list[dict[str, Any]]:
|
|
|
135
150
|
frontmatter["categories"] = ["code"]
|
|
136
151
|
elif isinstance(frontmatter["categories"], str):
|
|
137
152
|
frontmatter["categories"] = [frontmatter["categories"]]
|
|
153
|
+
# Extract markdown body as system_prompt
|
|
154
|
+
frontmatter["system_prompt"] = extract_body(content)
|
|
138
155
|
agents.append(frontmatter)
|
|
139
156
|
except Exception:
|
|
140
157
|
# Skip files that can't be read or parsed
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
/package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/CLARITY-AUDITOR.md
RENAMED
|
File without changes
|
|
File without changes
|
/package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/DEVILS-ADVOCATE.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/INCENTIVE-MAPPER.md
RENAMED
|
File without changes
|
/package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/PRECEDENT-FINDER.md
RENAMED
|
File without changes
|
|
File without changes
|
/package/dist/templates/cc-native/{.claude/agents/cc-native → _cc-native/agents}/RISK-ASSESSOR.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|