aiwcli 0.10.3 → 0.11.1
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.js +28 -131
- package/dist/commands/init/index.js +3 -3
- package/dist/lib/gitignore-manager.d.ts +32 -0
- package/dist/lib/gitignore-manager.js +141 -2
- 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 +107 -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 +12 -12
- package/dist/templates/_shared/lib-ts/base/constants.ts +22 -15
- package/dist/templates/_shared/lib-ts/base/git-state.ts +1 -1
- package/dist/templates/_shared/lib-ts/base/hook-utils.ts +129 -50
- package/dist/templates/_shared/lib-ts/base/inference.ts +28 -21
- package/dist/templates/_shared/lib-ts/base/logger.ts +15 -2
- package/dist/templates/_shared/lib-ts/base/state-io.ts +9 -7
- package/dist/templates/_shared/lib-ts/base/stop-words.ts +131 -131
- package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +142 -0
- package/dist/templates/_shared/lib-ts/base/utils.ts +69 -69
- package/dist/templates/_shared/lib-ts/context/context-formatter.ts +30 -24
- package/dist/templates/_shared/lib-ts/context/context-selector.ts +50 -32
- package/dist/templates/_shared/lib-ts/context/context-store.ts +76 -48
- package/dist/templates/_shared/lib-ts/context/plan-manager.ts +43 -23
- package/dist/templates/_shared/lib-ts/context/task-tracker.ts +10 -6
- package/dist/templates/_shared/lib-ts/handoff/document-generator.ts +11 -10
- package/dist/templates/_shared/lib-ts/handoff/handoff-reader.ts +158 -0
- package/dist/templates/_shared/lib-ts/templates/formatters.ts +6 -4
- package/dist/templates/_shared/lib-ts/types.ts +68 -55
- package/dist/templates/_shared/scripts/resolve_context.ts +24 -0
- package/dist/templates/_shared/scripts/resume_handoff.ts +345 -0
- package/dist/templates/_shared/scripts/save_handoff.ts +3 -3
- package/dist/templates/_shared/scripts/status_line.ts +687 -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/CLAUDE.md +0 -2
- 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 +1027 -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 +156 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +792 -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 +144 -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/corroboration.ts +115 -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 +120 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +168 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/nul +3 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +250 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +275 -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 +107 -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 +240 -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 +385 -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 +14 -1
- package/oclif.manifest.json +1 -1
- package/package.json +2 -2
- 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 -177
- 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 -339
- package/dist/templates/_shared/lib/base/inference.py +0 -307
- package/dist/templates/_shared/lib/base/logger.py +0 -305
- package/dist/templates/_shared/lib/base/stop_words.py +0 -221
- package/dist/templates/_shared/lib/base/subprocess_utils.py +0 -46
- package/dist/templates/_shared/lib/base/utils.py +0 -263
- 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 -303
- 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/lib/templates/plan_context.py +0 -73
- 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 -716
- 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/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 -954
- 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 -1071
- 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
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
"""CC-Native shared library modules.
|
|
2
|
-
|
|
3
|
-
This package contains shared utilities for cc-native hooks:
|
|
4
|
-
- utils: Core utilities (eprint, sanitize, JSON parsing, artifact writing)
|
|
5
|
-
- state: Plan state file management and iteration tracking
|
|
6
|
-
- orchestrator: Plan complexity analysis and agent selection
|
|
7
|
-
- reviewers: CLI and agent-based plan review implementations
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from .utils import (
|
|
11
|
-
eprint,
|
|
12
|
-
sanitize_filename,
|
|
13
|
-
sanitize_title,
|
|
14
|
-
find_plan_file,
|
|
15
|
-
ReviewerResult,
|
|
16
|
-
OrchestratorResult,
|
|
17
|
-
CombinedReviewResult,
|
|
18
|
-
REVIEW_SCHEMA,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
from .state import (
|
|
22
|
-
get_state_file_path,
|
|
23
|
-
load_state,
|
|
24
|
-
save_state,
|
|
25
|
-
delete_state,
|
|
26
|
-
get_iteration_state,
|
|
27
|
-
update_iteration_state,
|
|
28
|
-
should_continue_iterating,
|
|
29
|
-
DEFAULT_REVIEW_ITERATIONS,
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
__all__ = [
|
|
33
|
-
# Core utilities
|
|
34
|
-
"eprint",
|
|
35
|
-
"sanitize_filename",
|
|
36
|
-
"sanitize_title",
|
|
37
|
-
"find_plan_file",
|
|
38
|
-
# Dataclasses
|
|
39
|
-
"ReviewerResult",
|
|
40
|
-
"OrchestratorResult",
|
|
41
|
-
"CombinedReviewResult",
|
|
42
|
-
# Constants
|
|
43
|
-
"REVIEW_SCHEMA",
|
|
44
|
-
"DEFAULT_REVIEW_ITERATIONS",
|
|
45
|
-
# State management
|
|
46
|
-
"get_state_file_path",
|
|
47
|
-
"load_state",
|
|
48
|
-
"save_state",
|
|
49
|
-
"delete_state",
|
|
50
|
-
"get_iteration_state",
|
|
51
|
-
"update_iteration_state",
|
|
52
|
-
"should_continue_iterating",
|
|
53
|
-
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"""Security and configuration constants."""
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
import os
|
|
4
|
-
|
|
5
|
-
# Feature flags
|
|
6
|
-
ENABLE_ROBUST_PLAN_WRITES = os.getenv('CC_NATIVE_ROBUST_WRITES', 'true').lower() == 'true'
|
|
7
|
-
ENABLE_PLAN_NOTIFICATIONS = os.getenv('CC_NATIVE_NOTIFICATIONS', 'false').lower() == 'true'
|
|
8
|
-
|
|
9
|
-
# Security constants
|
|
10
|
-
PLANS_DIR = Path.home() / ".claude" / "plans"
|
|
11
|
-
MAX_PLAN_PATH_LENGTH = 4096
|
|
12
|
-
MAX_ERROR_FILE_SIZE = 10 * 1024 # 10KB
|
|
13
|
-
|
|
14
|
-
# Performance constants
|
|
15
|
-
MAX_RETRY_ATTEMPTS = 2 # Fast-fail: 2 attempts max
|
|
16
|
-
RETRY_BACKOFF_MS = [500, 1000] # 0.5s, 1s (total 1.5s max)
|
|
17
|
-
MAX_TOTAL_RETRY_TIME_MS = 3000 # 3 seconds total, well under 5s hook timeout
|
|
18
|
-
|
|
19
|
-
def validate_plan_path(plan_path: str) -> Path:
|
|
20
|
-
"""
|
|
21
|
-
Validate and sanitize plan path to prevent traversal attacks.
|
|
22
|
-
|
|
23
|
-
Raises:
|
|
24
|
-
ValueError: If path is invalid, too long, or outside allowed directory
|
|
25
|
-
"""
|
|
26
|
-
# Input validation
|
|
27
|
-
if not plan_path or len(plan_path) > MAX_PLAN_PATH_LENGTH:
|
|
28
|
-
raise ValueError(f"Invalid plan path length: {len(plan_path) if plan_path else 0}")
|
|
29
|
-
|
|
30
|
-
if '\x00' in plan_path:
|
|
31
|
-
raise ValueError("Null bytes not allowed in path")
|
|
32
|
-
|
|
33
|
-
# Normalize and resolve to absolute canonical path
|
|
34
|
-
try:
|
|
35
|
-
resolved = Path(plan_path).resolve(strict=False)
|
|
36
|
-
except (OSError, RuntimeError) as e:
|
|
37
|
-
raise ValueError(f"Path resolution failed: {e}")
|
|
38
|
-
|
|
39
|
-
# Verify path is within allowed directory
|
|
40
|
-
try:
|
|
41
|
-
resolved.relative_to(PLANS_DIR)
|
|
42
|
-
except ValueError:
|
|
43
|
-
raise ValueError(f"Path outside allowed directory: {PLANS_DIR}")
|
|
44
|
-
|
|
45
|
-
return resolved
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Permanent debug logging for cc-native hooks.
|
|
3
|
-
|
|
4
|
-
Thin delegation layer over the unified logger (_shared/lib/base/logger.py).
|
|
5
|
-
Logs are written to context folder: _output/contexts/<context-id>/debug/hook-log.jsonl
|
|
6
|
-
Append-only, cleaned up when context is archived.
|
|
7
|
-
Can be disabled via CCNATIVE_DEBUG_DISABLE=1 environment variable.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
import os
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
from typing import Any, Optional
|
|
13
|
-
|
|
14
|
-
# Feature flag - set CCNATIVE_DEBUG_DISABLE=1 to turn off
|
|
15
|
-
DEBUG_ENABLED = os.environ.get("CCNATIVE_DEBUG_DISABLE", "").lower() not in ("1", "true", "yes")
|
|
16
|
-
|
|
17
|
-
# Import unified logger
|
|
18
|
-
try:
|
|
19
|
-
from _shared.lib.base.logger import hook_log
|
|
20
|
-
except ImportError:
|
|
21
|
-
# Fallback: try relative import path used by hooks
|
|
22
|
-
try:
|
|
23
|
-
import sys
|
|
24
|
-
_shared = Path(__file__).parent.parent.parent.parent / "_shared"
|
|
25
|
-
if str(_shared) not in sys.path:
|
|
26
|
-
sys.path.insert(0, str(_shared))
|
|
27
|
-
from lib.base.logger import hook_log
|
|
28
|
-
except ImportError:
|
|
29
|
-
# Last resort: no-op
|
|
30
|
-
def hook_log(*args, **kwargs):
|
|
31
|
-
pass
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def get_debug_dir(context_path: Path) -> Path:
|
|
35
|
-
"""Get or create debug directory within context folder.
|
|
36
|
-
|
|
37
|
-
Args:
|
|
38
|
-
context_path: Path to context folder (e.g., _output/contexts/<context-id>/)
|
|
39
|
-
|
|
40
|
-
Returns:
|
|
41
|
-
Path to debug folder: <context_path>/debug/
|
|
42
|
-
"""
|
|
43
|
-
debug_dir = context_path / "debug"
|
|
44
|
-
debug_dir.mkdir(parents=True, exist_ok=True)
|
|
45
|
-
return debug_dir
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def get_log_path(context_path: Path, session_name: str) -> Path:
|
|
49
|
-
"""Get log file path for this session.
|
|
50
|
-
|
|
51
|
-
Args:
|
|
52
|
-
context_path: Path to context folder
|
|
53
|
-
session_name: Session name/ID (will be sanitized)
|
|
54
|
-
|
|
55
|
-
Returns:
|
|
56
|
-
Path to log file: <context_path>/_output/debug/<session-name>.log
|
|
57
|
-
"""
|
|
58
|
-
safe_name = "".join(c if c.isalnum() or c in "-_" else "_" for c in session_name)[:64]
|
|
59
|
-
return get_debug_dir(context_path) / f"{safe_name}.log"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def debug_log(
|
|
63
|
-
context_path: Path,
|
|
64
|
-
session_name: str,
|
|
65
|
-
component: str,
|
|
66
|
-
message: str,
|
|
67
|
-
data: Optional[Any] = None
|
|
68
|
-
) -> None:
|
|
69
|
-
"""Write a debug log entry. Delegates to unified logger.
|
|
70
|
-
|
|
71
|
-
Args:
|
|
72
|
-
context_path: Path to context folder
|
|
73
|
-
session_name: Session name/ID
|
|
74
|
-
component: Component name (e.g., "agent", "orchestrator", "parse")
|
|
75
|
-
message: Log message
|
|
76
|
-
data: Optional data to include (will be JSON serialized)
|
|
77
|
-
"""
|
|
78
|
-
if not DEBUG_ENABLED:
|
|
79
|
-
return
|
|
80
|
-
|
|
81
|
-
hook_log(
|
|
82
|
-
"debug",
|
|
83
|
-
session_name,
|
|
84
|
-
message,
|
|
85
|
-
component=component,
|
|
86
|
-
data=data,
|
|
87
|
-
context_path=context_path,
|
|
88
|
-
stderr=False,
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
def debug_raw(
|
|
93
|
-
context_path: Path,
|
|
94
|
-
session_name: str,
|
|
95
|
-
component: str,
|
|
96
|
-
label: str,
|
|
97
|
-
raw: str,
|
|
98
|
-
max_len: int = 10000
|
|
99
|
-
) -> None:
|
|
100
|
-
"""Log raw output (stdout, stderr, etc). Delegates to unified logger.
|
|
101
|
-
|
|
102
|
-
Args:
|
|
103
|
-
context_path: Path to context folder
|
|
104
|
-
session_name: Session name/ID
|
|
105
|
-
component: Component name
|
|
106
|
-
label: Label for the raw content (e.g., "stdout", "stderr")
|
|
107
|
-
raw: Raw string content
|
|
108
|
-
max_len: Maximum characters to log (default 10000)
|
|
109
|
-
"""
|
|
110
|
-
if not DEBUG_ENABLED:
|
|
111
|
-
return
|
|
112
|
-
|
|
113
|
-
truncated = raw[:max_len] if len(raw) > max_len else raw
|
|
114
|
-
suffix = f" [TRUNCATED from {len(raw)} chars]" if len(raw) > max_len else ""
|
|
115
|
-
hook_log(
|
|
116
|
-
"debug",
|
|
117
|
-
session_name,
|
|
118
|
-
f"{label}{suffix}: {truncated}",
|
|
119
|
-
component=component,
|
|
120
|
-
context_path=context_path,
|
|
121
|
-
stderr=False,
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
def cleanup_debug_folder(context_path: Path) -> None:
|
|
126
|
-
"""Remove debug folder during context archive.
|
|
127
|
-
|
|
128
|
-
Called by archive_plan.py when archiving a context.
|
|
129
|
-
|
|
130
|
-
Args:
|
|
131
|
-
context_path: Path to context folder being archived
|
|
132
|
-
"""
|
|
133
|
-
try:
|
|
134
|
-
debug_dir = context_path / "debug"
|
|
135
|
-
if debug_dir.exists():
|
|
136
|
-
import shutil
|
|
137
|
-
shutil.rmtree(debug_dir)
|
|
138
|
-
except Exception:
|
|
139
|
-
pass # Best effort cleanup
|
|
@@ -1,362 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
CC-Native Plan Orchestrator Module.
|
|
3
|
-
|
|
4
|
-
Analyzes plan complexity and selects appropriate reviewers.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import json
|
|
8
|
-
import shutil
|
|
9
|
-
import subprocess
|
|
10
|
-
import sys
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
from typing import Any, Dict, List, Optional
|
|
13
|
-
|
|
14
|
-
# Import from parent lib
|
|
15
|
-
_lib_dir = Path(__file__).resolve().parent
|
|
16
|
-
sys.path.insert(0, str(_lib_dir))
|
|
17
|
-
|
|
18
|
-
from utils import OrchestratorResult, parse_json_maybe
|
|
19
|
-
from reviewers.base import AgentConfig, OrchestratorConfig
|
|
20
|
-
|
|
21
|
-
# Import logger
|
|
22
|
-
_shared_logger = Path(__file__).resolve().parent.parent.parent / "_shared" / "lib"
|
|
23
|
-
sys.path.insert(0, str(_shared_logger))
|
|
24
|
-
from base.logger import log_debug, log_info, log_warn, log_error
|
|
25
|
-
|
|
26
|
-
# Import shared subprocess utilities
|
|
27
|
-
_shared_lib = Path(__file__).resolve().parent.parent.parent / "_shared" / "lib" / "base"
|
|
28
|
-
sys.path.insert(0, str(_shared_lib))
|
|
29
|
-
from subprocess_utils import get_internal_subprocess_env
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# ---------------------------
|
|
33
|
-
# Constants
|
|
34
|
-
# ---------------------------
|
|
35
|
-
|
|
36
|
-
DEFAULT_AGENT_SELECTION: Dict[str, Any] = {
|
|
37
|
-
"simple": {"min": 3, "max": 3},
|
|
38
|
-
"medium": {"min": 8, "max": 8},
|
|
39
|
-
"high": {"min": 12, "max": 12},
|
|
40
|
-
"fallbackCount": 3,
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
DEFAULT_COMPLEXITY_CATEGORIES: List[str] = [
|
|
44
|
-
"code",
|
|
45
|
-
"infrastructure",
|
|
46
|
-
"documentation",
|
|
47
|
-
"life",
|
|
48
|
-
"business",
|
|
49
|
-
"design",
|
|
50
|
-
"research",
|
|
51
|
-
]
|
|
52
|
-
|
|
53
|
-
ORCHESTRATOR_SCHEMA: Dict[str, Any] = {
|
|
54
|
-
"type": "object",
|
|
55
|
-
"properties": {
|
|
56
|
-
"complexity": {"type": "string", "enum": ["simple", "medium", "high"]},
|
|
57
|
-
"category": {"type": "string", "enum": DEFAULT_COMPLEXITY_CATEGORIES},
|
|
58
|
-
"selectedAgents": {"type": "array", "items": {"type": "string"}},
|
|
59
|
-
"reasoning": {"type": "string"},
|
|
60
|
-
"skipReason": {"type": "string"},
|
|
61
|
-
},
|
|
62
|
-
"required": ["complexity", "category", "selectedAgents", "reasoning"],
|
|
63
|
-
"additionalProperties": False,
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def build_orchestrator_schema(
|
|
68
|
-
valid_agent_names: List[str],
|
|
69
|
-
categories: List[str],
|
|
70
|
-
) -> Dict[str, Any]:
|
|
71
|
-
"""Build orchestrator JSON schema with enum-constrained agent names.
|
|
72
|
-
|
|
73
|
-
When valid_agent_names is non-empty, selectedAgents items are constrained
|
|
74
|
-
to only those names via JSON schema enum. This prevents the LLM from
|
|
75
|
-
hallucinating or misspelling agent names.
|
|
76
|
-
|
|
77
|
-
Args:
|
|
78
|
-
valid_agent_names: List of valid agent names for enum constraint.
|
|
79
|
-
categories: List of valid complexity categories.
|
|
80
|
-
|
|
81
|
-
Returns:
|
|
82
|
-
JSON schema dict for orchestrator structured output.
|
|
83
|
-
"""
|
|
84
|
-
items_schema: Dict[str, Any] = {"type": "string"}
|
|
85
|
-
if valid_agent_names:
|
|
86
|
-
items_schema["enum"] = valid_agent_names
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
"type": "object",
|
|
90
|
-
"properties": {
|
|
91
|
-
"complexity": {"type": "string", "enum": ["simple", "medium", "high"]},
|
|
92
|
-
"category": {"type": "string", "enum": categories},
|
|
93
|
-
"selectedAgents": {
|
|
94
|
-
"type": "array",
|
|
95
|
-
"items": items_schema,
|
|
96
|
-
},
|
|
97
|
-
"reasoning": {"type": "string"},
|
|
98
|
-
"skipReason": {"type": "string"},
|
|
99
|
-
},
|
|
100
|
-
"required": ["complexity", "category", "selectedAgents", "reasoning"],
|
|
101
|
-
"additionalProperties": False,
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
# ---------------------------
|
|
106
|
-
# Output Parsing
|
|
107
|
-
# ---------------------------
|
|
108
|
-
|
|
109
|
-
def _parse_claude_output(raw: str) -> Optional[Dict[str, Any]]:
|
|
110
|
-
"""Parse Claude CLI JSON output, handling various formats.
|
|
111
|
-
|
|
112
|
-
Claude CLI can output in several formats:
|
|
113
|
-
- Direct structured_output dict
|
|
114
|
-
- Assistant message with StructuredOutput tool use
|
|
115
|
-
- List of events with assistant messages
|
|
116
|
-
|
|
117
|
-
Args:
|
|
118
|
-
raw: Raw stdout from Claude CLI
|
|
119
|
-
|
|
120
|
-
Returns:
|
|
121
|
-
Parsed JSON dict or None if parsing failed
|
|
122
|
-
"""
|
|
123
|
-
try:
|
|
124
|
-
result = json.loads(raw)
|
|
125
|
-
if isinstance(result, dict):
|
|
126
|
-
if "structured_output" in result:
|
|
127
|
-
log_debug("orchestrator", "Found structured_output in root dict", component="parse")
|
|
128
|
-
return result["structured_output"]
|
|
129
|
-
if result.get("type") == "assistant":
|
|
130
|
-
message = result.get("message", {})
|
|
131
|
-
content = message.get("content", [])
|
|
132
|
-
for item in content:
|
|
133
|
-
if isinstance(item, dict) and item.get("name") == "StructuredOutput":
|
|
134
|
-
log_debug("orchestrator", "Found StructuredOutput in assistant message content", component="parse")
|
|
135
|
-
return item.get("input", {})
|
|
136
|
-
log_debug("orchestrator", "Assistant message found but no StructuredOutput tool use in content", component="parse")
|
|
137
|
-
elif isinstance(result, list):
|
|
138
|
-
log_debug("orchestrator", f"Received list of {len(result)} events, searching for assistant message", component="parse")
|
|
139
|
-
for i, event in enumerate(result):
|
|
140
|
-
if not isinstance(event, dict):
|
|
141
|
-
continue
|
|
142
|
-
if event.get("type") == "assistant":
|
|
143
|
-
message = event.get("message", {})
|
|
144
|
-
content = message.get("content", [])
|
|
145
|
-
for item in content:
|
|
146
|
-
if isinstance(item, dict) and item.get("name") == "StructuredOutput":
|
|
147
|
-
log_debug("orchestrator", f"Found StructuredOutput in event[{i}] assistant message", component="parse")
|
|
148
|
-
return item.get("input", {})
|
|
149
|
-
log_debug("orchestrator", "No StructuredOutput found in any assistant message in event list", component="parse")
|
|
150
|
-
except json.JSONDecodeError as e:
|
|
151
|
-
log_warn("orchestrator", f"JSON decode error: {e}", component="parse")
|
|
152
|
-
except Exception as e:
|
|
153
|
-
log_error("orchestrator", f"Unexpected error during structured parsing: {e}", component="parse")
|
|
154
|
-
|
|
155
|
-
# Fallback to heuristic extraction
|
|
156
|
-
log_debug("orchestrator", "No structured output found, falling back to heuristic JSON extraction", component="parse")
|
|
157
|
-
return parse_json_maybe(raw)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
# ---------------------------
|
|
161
|
-
# Orchestrator
|
|
162
|
-
# ---------------------------
|
|
163
|
-
|
|
164
|
-
def run_orchestrator(
|
|
165
|
-
plan: str,
|
|
166
|
-
agent_library: List[AgentConfig],
|
|
167
|
-
config: OrchestratorConfig,
|
|
168
|
-
settings: Dict[str, Any],
|
|
169
|
-
mandatory_names: Optional[set] = None,
|
|
170
|
-
) -> OrchestratorResult:
|
|
171
|
-
"""Run the orchestrator agent to analyze plan complexity and select reviewers.
|
|
172
|
-
|
|
173
|
-
Args:
|
|
174
|
-
plan: The plan content to analyze
|
|
175
|
-
agent_library: List of available agents
|
|
176
|
-
config: Orchestrator configuration (model, timeout)
|
|
177
|
-
settings: Agent review settings (agentSelection, complexityCategories)
|
|
178
|
-
mandatory_names: Set of agent names that always run (excluded from selection)
|
|
179
|
-
|
|
180
|
-
Returns:
|
|
181
|
-
OrchestratorResult with complexity, category, and selected agents
|
|
182
|
-
"""
|
|
183
|
-
log_info("orchestrator", "Starting plan analysis...")
|
|
184
|
-
|
|
185
|
-
if mandatory_names is None:
|
|
186
|
-
mandatory_names = set()
|
|
187
|
-
|
|
188
|
-
selection = settings.get("agentSelection", DEFAULT_AGENT_SELECTION)
|
|
189
|
-
categories = settings.get("complexityCategories", DEFAULT_COMPLEXITY_CATEGORIES)
|
|
190
|
-
fallback_count = selection.get("fallbackCount", 2)
|
|
191
|
-
|
|
192
|
-
# Filter out mandatory agents — they always run, no need for orchestrator to select them
|
|
193
|
-
non_mandatory = [a for a in agent_library if a.enabled and a.name not in mandatory_names]
|
|
194
|
-
valid_names = [a.name for a in non_mandatory]
|
|
195
|
-
|
|
196
|
-
log_debug("orchestrator", f"Mandatory agents (always run): {sorted(mandatory_names)}")
|
|
197
|
-
log_debug("orchestrator", f"Non-mandatory agents for selection: {valid_names}")
|
|
198
|
-
|
|
199
|
-
claude_path = shutil.which("claude")
|
|
200
|
-
if claude_path is None:
|
|
201
|
-
log_warn("orchestrator", "Claude CLI not found on PATH, falling back to medium complexity")
|
|
202
|
-
return OrchestratorResult(
|
|
203
|
-
complexity="medium",
|
|
204
|
-
category="code",
|
|
205
|
-
selected_agents=[a.name for a in non_mandatory][:fallback_count],
|
|
206
|
-
reasoning="Orchestrator skipped - Claude CLI not found",
|
|
207
|
-
error="claude CLI not found on PATH",
|
|
208
|
-
)
|
|
209
|
-
|
|
210
|
-
log_debug("orchestrator", f"Found Claude CLI at: {claude_path}")
|
|
211
|
-
|
|
212
|
-
# Build agent list from non-mandatory agents only
|
|
213
|
-
agent_list = "\n".join([
|
|
214
|
-
f"- {a.name} [{', '.join(a.categories)}]\n"
|
|
215
|
-
f" Focus: {a.focus}\n"
|
|
216
|
-
f" Expertise: {a.description}"
|
|
217
|
-
for a in non_mandatory
|
|
218
|
-
])
|
|
219
|
-
category_list = "/".join(categories)
|
|
220
|
-
|
|
221
|
-
# Compute additional agent counts (total minus mandatory count)
|
|
222
|
-
mandatory_count = len([a for a in agent_library if a.name in mandatory_names])
|
|
223
|
-
simple_additional = max(0, selection.get("simple", {}).get("max", 3) - mandatory_count)
|
|
224
|
-
medium_additional = max(0, selection.get("medium", {}).get("max", 8) - mandatory_count)
|
|
225
|
-
high_additional = max(0, selection.get("high", {}).get("max", 12) - mandatory_count)
|
|
226
|
-
|
|
227
|
-
# System prompt with orchestrator instructions
|
|
228
|
-
system_prompt = """You are a plan orchestrator for code review. Your job is to analyze plans and select appropriate reviewer agents.
|
|
229
|
-
|
|
230
|
-
You MUST call StructuredOutput immediately with your analysis. Do NOT ask questions or use any other tools.
|
|
231
|
-
|
|
232
|
-
When selecting agents:
|
|
233
|
-
- Match agent expertise to plan requirements
|
|
234
|
-
- Consider what each agent specializes in
|
|
235
|
-
- Only select agents whose categories match the plan category
|
|
236
|
-
- Fewer agents for simple plans, more for complex plans"""
|
|
237
|
-
|
|
238
|
-
# User prompt with plan and agent list
|
|
239
|
-
prompt = f"""Analyze this plan and select appropriate reviewer agents.
|
|
240
|
-
|
|
241
|
-
Available agents (select ONLY from this list):
|
|
242
|
-
{agent_list}
|
|
243
|
-
|
|
244
|
-
Selection rules (number of ADDITIONAL agents to select from the list above):
|
|
245
|
-
- simple complexity = {simple_additional} agents
|
|
246
|
-
- medium complexity = {medium_additional} agents
|
|
247
|
-
- high complexity = {high_additional} agents
|
|
248
|
-
- Only select agents whose categories match the plan category ({category_list})
|
|
249
|
-
- Non-technical plans (life, business) typically need 0 code-focused agents
|
|
250
|
-
- Note: mandatory agents run separately and are NOT listed above
|
|
251
|
-
|
|
252
|
-
PLAN:
|
|
253
|
-
<<<
|
|
254
|
-
{plan}
|
|
255
|
-
>>>
|
|
256
|
-
|
|
257
|
-
Call StructuredOutput now with: complexity, category, selectedAgents, reasoning"""
|
|
258
|
-
|
|
259
|
-
# Use dynamic schema with enum constraint when we have valid agent names
|
|
260
|
-
schema = build_orchestrator_schema(valid_names, categories) if valid_names else ORCHESTRATOR_SCHEMA
|
|
261
|
-
schema_json = json.dumps(schema, ensure_ascii=False)
|
|
262
|
-
|
|
263
|
-
cmd_args = [
|
|
264
|
-
claude_path,
|
|
265
|
-
"-p", # Enable print mode to read prompt from stdin
|
|
266
|
-
"--model", config.model,
|
|
267
|
-
"--output-format", "json",
|
|
268
|
-
"--json-schema", schema_json,
|
|
269
|
-
"--max-turns", "3", # Single-turn with buffer for tool call + result
|
|
270
|
-
"--setting-sources", "", # Disable PAI context interference
|
|
271
|
-
"--system-prompt", system_prompt,
|
|
272
|
-
]
|
|
273
|
-
|
|
274
|
-
log_info("orchestrator", f"Running with model: {config.model}, timeout: {config.timeout}s")
|
|
275
|
-
|
|
276
|
-
# Get environment for internal subprocess (bypasses hooks)
|
|
277
|
-
env = get_internal_subprocess_env()
|
|
278
|
-
|
|
279
|
-
try:
|
|
280
|
-
p = subprocess.run(
|
|
281
|
-
cmd_args,
|
|
282
|
-
input=prompt,
|
|
283
|
-
text=True,
|
|
284
|
-
capture_output=True,
|
|
285
|
-
timeout=config.timeout,
|
|
286
|
-
encoding="utf-8",
|
|
287
|
-
errors="replace",
|
|
288
|
-
env=env,
|
|
289
|
-
)
|
|
290
|
-
except subprocess.TimeoutExpired:
|
|
291
|
-
log_warn("orchestrator", f"TIMEOUT after {config.timeout}s, falling back to medium complexity")
|
|
292
|
-
return OrchestratorResult(
|
|
293
|
-
complexity="medium",
|
|
294
|
-
category="code",
|
|
295
|
-
selected_agents=[a.name for a in non_mandatory][:fallback_count],
|
|
296
|
-
reasoning="Orchestrator timed out - defaulting to medium complexity",
|
|
297
|
-
error=f"Orchestrator timed out after {config.timeout}s",
|
|
298
|
-
)
|
|
299
|
-
except Exception as ex:
|
|
300
|
-
log_error("orchestrator", f"Exception: {ex}, falling back to medium complexity")
|
|
301
|
-
return OrchestratorResult(
|
|
302
|
-
complexity="medium",
|
|
303
|
-
category="code",
|
|
304
|
-
selected_agents=[a.name for a in non_mandatory][:fallback_count],
|
|
305
|
-
reasoning=f"Orchestrator failed: {ex}",
|
|
306
|
-
error=str(ex),
|
|
307
|
-
)
|
|
308
|
-
|
|
309
|
-
log_debug("orchestrator", f"Exit code: {p.returncode}")
|
|
310
|
-
|
|
311
|
-
raw = (p.stdout or "").strip()
|
|
312
|
-
if p.stderr:
|
|
313
|
-
log_debug("orchestrator", f"stderr: {p.stderr[:300]}")
|
|
314
|
-
|
|
315
|
-
obj = _parse_claude_output(raw)
|
|
316
|
-
|
|
317
|
-
# Debug logging to diagnose empty selectedAgents issue
|
|
318
|
-
log_debug("orchestrator", f"Raw output length: {len(raw)} chars")
|
|
319
|
-
if raw:
|
|
320
|
-
log_debug("orchestrator", f"Raw output (first 500 chars): {raw[:500]}")
|
|
321
|
-
log_debug("orchestrator", f"Parsed obj: {obj}")
|
|
322
|
-
if obj:
|
|
323
|
-
log_debug("orchestrator", f"obj keys: {list(obj.keys())}")
|
|
324
|
-
log_debug("orchestrator", f"selectedAgents value: {obj.get('selectedAgents', 'MISSING')}")
|
|
325
|
-
log_debug("orchestrator", f"reasoning value: {obj.get('reasoning', 'MISSING')}")
|
|
326
|
-
|
|
327
|
-
if not obj:
|
|
328
|
-
log_warn("orchestrator", "Failed to parse output, falling back to medium complexity")
|
|
329
|
-
return OrchestratorResult(
|
|
330
|
-
complexity="medium",
|
|
331
|
-
category="code",
|
|
332
|
-
selected_agents=[a.name for a in non_mandatory][:fallback_count],
|
|
333
|
-
reasoning="Orchestrator output could not be parsed",
|
|
334
|
-
error="Failed to parse orchestrator output",
|
|
335
|
-
)
|
|
336
|
-
|
|
337
|
-
# Extract and validate fields
|
|
338
|
-
complexity = obj.get("complexity", "medium")
|
|
339
|
-
if complexity not in ("simple", "medium", "high"):
|
|
340
|
-
complexity = "medium"
|
|
341
|
-
|
|
342
|
-
category = obj.get("category", "code")
|
|
343
|
-
if category not in categories:
|
|
344
|
-
category = "code"
|
|
345
|
-
|
|
346
|
-
selected_agents = obj.get("selectedAgents", [])
|
|
347
|
-
if not isinstance(selected_agents, list):
|
|
348
|
-
selected_agents = []
|
|
349
|
-
|
|
350
|
-
reasoning = str(obj.get("reasoning", "")).strip() or "No reasoning provided"
|
|
351
|
-
skip_reason = obj.get("skipReason")
|
|
352
|
-
|
|
353
|
-
log_info("orchestrator", f"Result: complexity={complexity}, category={category}, agents={selected_agents}")
|
|
354
|
-
log_debug("orchestrator", f"Reasoning: {reasoning}")
|
|
355
|
-
|
|
356
|
-
return OrchestratorResult(
|
|
357
|
-
complexity=complexity,
|
|
358
|
-
category=category,
|
|
359
|
-
selected_agents=selected_agents,
|
|
360
|
-
reasoning=reasoning,
|
|
361
|
-
skip_reason=skip_reason if skip_reason else None,
|
|
362
|
-
)
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"""CC-Native Plan Reviewers Module.
|
|
2
|
-
|
|
3
|
-
Provides CLI and agent-based plan review implementations.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from .base import (
|
|
7
|
-
ReviewerResult,
|
|
8
|
-
REVIEW_SCHEMA,
|
|
9
|
-
REVIEW_PROMPT_PREFIX,
|
|
10
|
-
AGENT_REVIEW_PROMPT_PREFIX,
|
|
11
|
-
AgentConfig,
|
|
12
|
-
OrchestratorConfig,
|
|
13
|
-
)
|
|
14
|
-
from .codex import run_codex_review
|
|
15
|
-
from .gemini import run_gemini_review
|
|
16
|
-
from .agent import run_agent_review
|
|
17
|
-
|
|
18
|
-
__all__ = [
|
|
19
|
-
"ReviewerResult",
|
|
20
|
-
"REVIEW_SCHEMA",
|
|
21
|
-
"REVIEW_PROMPT_PREFIX",
|
|
22
|
-
"AGENT_REVIEW_PROMPT_PREFIX",
|
|
23
|
-
"AgentConfig",
|
|
24
|
-
"OrchestratorConfig",
|
|
25
|
-
"run_codex_review",
|
|
26
|
-
"run_gemini_review",
|
|
27
|
-
"run_agent_review",
|
|
28
|
-
]
|
package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/__init__.cpython-313.pyc
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|