htmlgraph 0.23.5__py3-none-any.whl → 0.24.1__py3-none-any.whl
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.
- htmlgraph/__init__.py +5 -1
- htmlgraph/cigs/__init__.py +77 -0
- htmlgraph/cigs/autonomy.py +385 -0
- htmlgraph/cigs/cost.py +475 -0
- htmlgraph/cigs/messages_basic.py +472 -0
- htmlgraph/cigs/messaging.py +365 -0
- htmlgraph/cigs/models.py +771 -0
- htmlgraph/cigs/pattern_storage.py +427 -0
- htmlgraph/cigs/patterns.py +503 -0
- htmlgraph/cigs/posttool_analyzer.py +234 -0
- htmlgraph/cigs/tracker.py +317 -0
- htmlgraph/cli.py +413 -11
- htmlgraph/hooks/cigs_pretool_enforcer.py +350 -0
- htmlgraph/hooks/posttooluse.py +50 -2
- htmlgraph/hooks/task_enforcer.py +60 -4
- htmlgraph/models.py +14 -1
- htmlgraph/orchestration/headless_spawner.py +519 -21
- htmlgraph/orchestrator-system-prompt-optimized.txt +259 -53
- htmlgraph/reflection.py +442 -0
- htmlgraph/sdk.py +26 -9
- {htmlgraph-0.23.5.dist-info → htmlgraph-0.24.1.dist-info}/METADATA +2 -1
- {htmlgraph-0.23.5.dist-info → htmlgraph-0.24.1.dist-info}/RECORD +29 -17
- {htmlgraph-0.23.5.data → htmlgraph-0.24.1.data}/data/htmlgraph/dashboard.html +0 -0
- {htmlgraph-0.23.5.data → htmlgraph-0.24.1.data}/data/htmlgraph/styles.css +0 -0
- {htmlgraph-0.23.5.data → htmlgraph-0.24.1.data}/data/htmlgraph/templates/AGENTS.md.template +0 -0
- {htmlgraph-0.23.5.data → htmlgraph-0.24.1.data}/data/htmlgraph/templates/CLAUDE.md.template +0 -0
- {htmlgraph-0.23.5.data → htmlgraph-0.24.1.data}/data/htmlgraph/templates/GEMINI.md.template +0 -0
- {htmlgraph-0.23.5.dist-info → htmlgraph-0.24.1.dist-info}/WHEEL +0 -0
- {htmlgraph-0.23.5.dist-info → htmlgraph-0.24.1.dist-info}/entry_points.txt +0 -0
htmlgraph/cli.py
CHANGED
|
@@ -1209,16 +1209,17 @@ def cmd_session_start_info(args: argparse.Namespace) -> None:
|
|
|
1209
1209
|
print(json.dumps(info, indent=2, default=str))
|
|
1210
1210
|
else:
|
|
1211
1211
|
# Human-readable format
|
|
1212
|
-
status = info["status"]
|
|
1212
|
+
status: dict = info["status"] # type: ignore
|
|
1213
1213
|
print("=" * 80)
|
|
1214
1214
|
print("SESSION START INFO")
|
|
1215
1215
|
print("=" * 80)
|
|
1216
1216
|
|
|
1217
1217
|
# Project status
|
|
1218
1218
|
print(f"\nProject: {status.get('project_name', 'HtmlGraph')}")
|
|
1219
|
-
print(f"Total
|
|
1220
|
-
print(f"In progress: {status.get('
|
|
1221
|
-
|
|
1219
|
+
print(f"Total features: {status.get('total_features', 0)}")
|
|
1220
|
+
print(f"In progress: {status.get('wip_count', 0)}")
|
|
1221
|
+
by_status = status.get("by_status", {})
|
|
1222
|
+
print(f"Completed: {by_status.get('done', 0)}")
|
|
1222
1223
|
|
|
1223
1224
|
# Active work item (validation status)
|
|
1224
1225
|
active_work = info.get("active_work")
|
|
@@ -3012,6 +3013,201 @@ def cmd_orchestrator_reset_violations(args: argparse.Namespace) -> None:
|
|
|
3012
3013
|
print("You can now continue with delegation workflow")
|
|
3013
3014
|
|
|
3014
3015
|
|
|
3016
|
+
def cmd_orchestrator_acknowledge_violation(args: argparse.Namespace) -> None:
|
|
3017
|
+
"""Acknowledge circuit breaker violation and reset state."""
|
|
3018
|
+
from htmlgraph.orchestrator_mode import OrchestratorModeManager
|
|
3019
|
+
|
|
3020
|
+
manager = OrchestratorModeManager(args.graph_dir)
|
|
3021
|
+
|
|
3022
|
+
# Check if circuit breaker is triggered
|
|
3023
|
+
if not manager.is_circuit_breaker_triggered():
|
|
3024
|
+
print("ℹ️ No circuit breaker to acknowledge")
|
|
3025
|
+
print("Current violations:", manager.get_violation_count())
|
|
3026
|
+
return
|
|
3027
|
+
|
|
3028
|
+
# Reset violations and circuit breaker
|
|
3029
|
+
manager.reset_violations()
|
|
3030
|
+
|
|
3031
|
+
print("✓ Circuit breaker acknowledged and reset")
|
|
3032
|
+
print("Violation counter: cleared")
|
|
3033
|
+
print("You can now continue with delegation workflow")
|
|
3034
|
+
|
|
3035
|
+
|
|
3036
|
+
def cmd_cigs_status(args: argparse.Namespace) -> None:
|
|
3037
|
+
"""Show current session CIGS status."""
|
|
3038
|
+
from pathlib import Path
|
|
3039
|
+
|
|
3040
|
+
from htmlgraph.cigs.autonomy import AutonomyRecommender
|
|
3041
|
+
from htmlgraph.cigs.pattern_storage import PatternStorage
|
|
3042
|
+
from htmlgraph.cigs.tracker import ViolationTracker
|
|
3043
|
+
|
|
3044
|
+
graph_dir = Path(args.graph_dir or ".htmlgraph")
|
|
3045
|
+
|
|
3046
|
+
# Get violation tracker
|
|
3047
|
+
tracker = ViolationTracker(graph_dir)
|
|
3048
|
+
summary = tracker.get_session_violations()
|
|
3049
|
+
|
|
3050
|
+
# Get pattern storage
|
|
3051
|
+
pattern_storage = PatternStorage(graph_dir)
|
|
3052
|
+
patterns = pattern_storage.get_anti_patterns()
|
|
3053
|
+
|
|
3054
|
+
# Get autonomy recommendation
|
|
3055
|
+
recommender = AutonomyRecommender()
|
|
3056
|
+
autonomy = recommender.recommend(summary, patterns)
|
|
3057
|
+
|
|
3058
|
+
# Print formatted status
|
|
3059
|
+
print("=== CIGS Status ===\n")
|
|
3060
|
+
print(f"Session: {summary.session_id}")
|
|
3061
|
+
print(f"Violations: {summary.total_violations}/3")
|
|
3062
|
+
print(f"Compliance Rate: {summary.compliance_rate:.1%}")
|
|
3063
|
+
print(f"Total Waste: {summary.total_waste_tokens} tokens")
|
|
3064
|
+
print(
|
|
3065
|
+
f"Circuit Breaker: {'🚨 TRIGGERED' if summary.circuit_breaker_triggered else 'Not triggered'}"
|
|
3066
|
+
)
|
|
3067
|
+
|
|
3068
|
+
if summary.violations_by_type:
|
|
3069
|
+
print("\nViolation Breakdown:")
|
|
3070
|
+
for vtype, count in summary.violations_by_type.items():
|
|
3071
|
+
print(f" • {vtype}: {count}")
|
|
3072
|
+
|
|
3073
|
+
print(f"\nAutonomy Level: {autonomy.level.upper()}")
|
|
3074
|
+
print(f"Messaging Intensity: {autonomy.messaging_intensity}")
|
|
3075
|
+
print(f"Enforcement Mode: {autonomy.enforcement_mode}")
|
|
3076
|
+
|
|
3077
|
+
if patterns:
|
|
3078
|
+
print(f"\nAnti-Patterns Detected: {len(patterns)}")
|
|
3079
|
+
for pattern in patterns[:3]:
|
|
3080
|
+
print(f" • {pattern.name} ({pattern.occurrence_count}x)")
|
|
3081
|
+
|
|
3082
|
+
|
|
3083
|
+
def cmd_cigs_summary(args: argparse.Namespace) -> None:
|
|
3084
|
+
"""Show detailed session summary."""
|
|
3085
|
+
from pathlib import Path
|
|
3086
|
+
|
|
3087
|
+
from htmlgraph.cigs.tracker import ViolationTracker
|
|
3088
|
+
|
|
3089
|
+
graph_dir = Path(args.graph_dir or ".htmlgraph")
|
|
3090
|
+
tracker = ViolationTracker(graph_dir)
|
|
3091
|
+
|
|
3092
|
+
# Get session ID (default to current)
|
|
3093
|
+
session_id = args.session_id or tracker._session_id
|
|
3094
|
+
|
|
3095
|
+
if not session_id:
|
|
3096
|
+
print("⚠️ No active session. Specify --session-id to view past sessions.")
|
|
3097
|
+
return
|
|
3098
|
+
|
|
3099
|
+
summary = tracker.get_session_violations(session_id)
|
|
3100
|
+
|
|
3101
|
+
# Print detailed summary
|
|
3102
|
+
print("=== CIGS Session Summary ===\n")
|
|
3103
|
+
print(f"Session ID: {summary.session_id}")
|
|
3104
|
+
print("─" * 50)
|
|
3105
|
+
print(f"Total Violations: {summary.total_violations}")
|
|
3106
|
+
print(f"Compliance Rate: {summary.compliance_rate:.1%}")
|
|
3107
|
+
print(f"Total Waste: {summary.total_waste_tokens} tokens")
|
|
3108
|
+
print(
|
|
3109
|
+
f"Circuit Breaker: {'🚨 TRIGGERED' if summary.circuit_breaker_triggered else 'Not triggered'}"
|
|
3110
|
+
)
|
|
3111
|
+
|
|
3112
|
+
if summary.violations_by_type:
|
|
3113
|
+
print("\nViolation Breakdown:")
|
|
3114
|
+
for vtype, count in summary.violations_by_type.items():
|
|
3115
|
+
print(f" • {vtype}: {count}")
|
|
3116
|
+
|
|
3117
|
+
if summary.violations:
|
|
3118
|
+
print(f"\nRecent Violations ({len(summary.violations)}):")
|
|
3119
|
+
for v in summary.violations[-5:]:
|
|
3120
|
+
print(f" • {v.tool} - {v.violation_type} - {v.waste_tokens} tokens wasted")
|
|
3121
|
+
print(f" Should have: {v.should_have_delegated_to}")
|
|
3122
|
+
|
|
3123
|
+
|
|
3124
|
+
def cmd_cigs_patterns(args: argparse.Namespace) -> None:
|
|
3125
|
+
"""List all detected patterns with occurrence counts."""
|
|
3126
|
+
from pathlib import Path
|
|
3127
|
+
|
|
3128
|
+
from htmlgraph.cigs.pattern_storage import PatternStorage
|
|
3129
|
+
|
|
3130
|
+
graph_dir = Path(args.graph_dir or ".htmlgraph")
|
|
3131
|
+
pattern_storage = PatternStorage(graph_dir)
|
|
3132
|
+
|
|
3133
|
+
# Get all patterns
|
|
3134
|
+
anti_patterns = pattern_storage.get_anti_patterns()
|
|
3135
|
+
good_patterns = pattern_storage.get_good_patterns()
|
|
3136
|
+
|
|
3137
|
+
# Print anti-patterns
|
|
3138
|
+
print("=== CIGS Pattern Analysis ===\n")
|
|
3139
|
+
|
|
3140
|
+
if anti_patterns:
|
|
3141
|
+
print("Anti-Patterns Detected:")
|
|
3142
|
+
print("─" * 50)
|
|
3143
|
+
for pattern in sorted(
|
|
3144
|
+
anti_patterns, key=lambda p: p.occurrence_count, reverse=True
|
|
3145
|
+
):
|
|
3146
|
+
print(f"\n{pattern.name}")
|
|
3147
|
+
print(f" Occurrences: {pattern.occurrence_count}")
|
|
3148
|
+
print(f" Description: {pattern.description}")
|
|
3149
|
+
print(f" Sessions Affected: {len(pattern.sessions_affected)}")
|
|
3150
|
+
|
|
3151
|
+
if pattern.correct_approach:
|
|
3152
|
+
print(f" ✓ Fix: {pattern.correct_approach}")
|
|
3153
|
+
|
|
3154
|
+
if pattern.delegation_suggestion:
|
|
3155
|
+
print(f" 💡 Instead: {pattern.delegation_suggestion}")
|
|
3156
|
+
else:
|
|
3157
|
+
print("No anti-patterns detected yet.")
|
|
3158
|
+
|
|
3159
|
+
# Print good patterns
|
|
3160
|
+
if good_patterns:
|
|
3161
|
+
print("\n\nGood Patterns Observed:")
|
|
3162
|
+
print("─" * 50)
|
|
3163
|
+
for pattern in sorted(
|
|
3164
|
+
good_patterns, key=lambda p: p.occurrence_count, reverse=True
|
|
3165
|
+
):
|
|
3166
|
+
print(f"\n{pattern.name}")
|
|
3167
|
+
print(f" Occurrences: {pattern.occurrence_count}")
|
|
3168
|
+
print(f" Description: {pattern.description}")
|
|
3169
|
+
print(f" Sessions Affected: {len(pattern.sessions_affected)}")
|
|
3170
|
+
|
|
3171
|
+
|
|
3172
|
+
def cmd_cigs_reset_violations(args: argparse.Namespace) -> None:
|
|
3173
|
+
"""Reset violation count for current session."""
|
|
3174
|
+
from pathlib import Path
|
|
3175
|
+
|
|
3176
|
+
from htmlgraph.cigs.tracker import ViolationTracker
|
|
3177
|
+
|
|
3178
|
+
graph_dir = Path(args.graph_dir or ".htmlgraph")
|
|
3179
|
+
tracker = ViolationTracker(graph_dir)
|
|
3180
|
+
|
|
3181
|
+
# Get current session
|
|
3182
|
+
session_id = tracker._session_id
|
|
3183
|
+
if not session_id:
|
|
3184
|
+
print("⚠️ No active session")
|
|
3185
|
+
return
|
|
3186
|
+
|
|
3187
|
+
# Check current violations
|
|
3188
|
+
summary = tracker.get_session_violations()
|
|
3189
|
+
|
|
3190
|
+
if summary.total_violations == 0:
|
|
3191
|
+
print("ℹ️ No violations to reset")
|
|
3192
|
+
return
|
|
3193
|
+
|
|
3194
|
+
# Confirm reset
|
|
3195
|
+
if not args.yes:
|
|
3196
|
+
print(f"Current violations: {summary.total_violations}")
|
|
3197
|
+
print(f"Total waste: {summary.total_waste_tokens} tokens")
|
|
3198
|
+
response = input("\nReset violations for current session? [y/N]: ")
|
|
3199
|
+
if response.lower() not in ("y", "yes"):
|
|
3200
|
+
print("Reset cancelled")
|
|
3201
|
+
return
|
|
3202
|
+
|
|
3203
|
+
# Clear violations file
|
|
3204
|
+
tracker.clear_session_file()
|
|
3205
|
+
|
|
3206
|
+
print("✓ Violations reset for current session")
|
|
3207
|
+
print("Circuit breaker: cleared")
|
|
3208
|
+
print("Starting fresh for this session")
|
|
3209
|
+
|
|
3210
|
+
|
|
3015
3211
|
def cmd_publish(args: argparse.Namespace) -> None:
|
|
3016
3212
|
"""Build and publish the package to PyPI (Interoperable)."""
|
|
3017
3213
|
import shutil
|
|
@@ -3586,6 +3782,88 @@ def create_default_index(path: Path) -> None:
|
|
|
3586
3782
|
)
|
|
3587
3783
|
|
|
3588
3784
|
|
|
3785
|
+
def install_htmlgraph_plugin(args: argparse.Namespace) -> None:
|
|
3786
|
+
"""Install/upgrade HtmlGraph plugin using documented Claude Code commands."""
|
|
3787
|
+
verbose = not (args.quiet or args.format == "json")
|
|
3788
|
+
|
|
3789
|
+
if verbose:
|
|
3790
|
+
print("\n📦 Installing/upgrading HtmlGraph plugin...\n")
|
|
3791
|
+
|
|
3792
|
+
# Step 1: Update marketplace
|
|
3793
|
+
try:
|
|
3794
|
+
if verbose:
|
|
3795
|
+
print(" Updating marketplace...")
|
|
3796
|
+
result = subprocess.run(
|
|
3797
|
+
["claude", "plugin", "marketplace", "update", "htmlgraph"],
|
|
3798
|
+
capture_output=True,
|
|
3799
|
+
text=True,
|
|
3800
|
+
check=False,
|
|
3801
|
+
)
|
|
3802
|
+
if result.returncode == 0:
|
|
3803
|
+
if verbose:
|
|
3804
|
+
print(" ✓ Marketplace updated")
|
|
3805
|
+
else:
|
|
3806
|
+
# Marketplace errors are non-blocking
|
|
3807
|
+
if (
|
|
3808
|
+
"not found" in result.stderr.lower()
|
|
3809
|
+
or "no marketplace" in result.stderr.lower()
|
|
3810
|
+
):
|
|
3811
|
+
if verbose:
|
|
3812
|
+
print(" ℹ Marketplace not configured (OK, continuing)")
|
|
3813
|
+
elif verbose:
|
|
3814
|
+
print(f" ⚠ Marketplace update: {result.stderr.strip()}")
|
|
3815
|
+
except FileNotFoundError:
|
|
3816
|
+
if verbose:
|
|
3817
|
+
print(" ⚠ 'claude' command not found")
|
|
3818
|
+
except Exception as e:
|
|
3819
|
+
if verbose:
|
|
3820
|
+
print(f" ⚠ Error updating marketplace: {e}")
|
|
3821
|
+
|
|
3822
|
+
# Step 2: Try update first (documented command for latest version)
|
|
3823
|
+
try:
|
|
3824
|
+
if verbose:
|
|
3825
|
+
print(" Updating plugin to latest version...")
|
|
3826
|
+
result = subprocess.run(
|
|
3827
|
+
["claude", "plugin", "update", "htmlgraph"],
|
|
3828
|
+
capture_output=True,
|
|
3829
|
+
text=True,
|
|
3830
|
+
check=False,
|
|
3831
|
+
)
|
|
3832
|
+
if result.returncode == 0:
|
|
3833
|
+
if verbose:
|
|
3834
|
+
print(" ✓ Plugin updated successfully")
|
|
3835
|
+
else:
|
|
3836
|
+
# If update fails (plugin not installed), fallback to install
|
|
3837
|
+
if (
|
|
3838
|
+
"not installed" in result.stderr.lower()
|
|
3839
|
+
or "not found" in result.stderr.lower()
|
|
3840
|
+
):
|
|
3841
|
+
if verbose:
|
|
3842
|
+
print(" ℹ Plugin not yet installed, installing...")
|
|
3843
|
+
install_result = subprocess.run(
|
|
3844
|
+
["claude", "plugin", "install", "htmlgraph"],
|
|
3845
|
+
capture_output=True,
|
|
3846
|
+
text=True,
|
|
3847
|
+
check=False,
|
|
3848
|
+
)
|
|
3849
|
+
if install_result.returncode == 0:
|
|
3850
|
+
if verbose:
|
|
3851
|
+
print(" ✓ Plugin installed successfully")
|
|
3852
|
+
elif verbose:
|
|
3853
|
+
print(f" ⚠ Plugin install: {install_result.stderr.strip()}")
|
|
3854
|
+
elif verbose:
|
|
3855
|
+
print(f" ⚠ Plugin update: {result.stderr.strip()}")
|
|
3856
|
+
except FileNotFoundError:
|
|
3857
|
+
if verbose:
|
|
3858
|
+
print(" ⚠ 'claude' command not found")
|
|
3859
|
+
except Exception as e:
|
|
3860
|
+
if verbose:
|
|
3861
|
+
print(f" ⚠ Error updating plugin: {e}")
|
|
3862
|
+
|
|
3863
|
+
if verbose:
|
|
3864
|
+
print("\n✓ Plugin installation complete\n")
|
|
3865
|
+
|
|
3866
|
+
|
|
3589
3867
|
def cmd_claude(args: argparse.Namespace) -> None:
|
|
3590
3868
|
"""Start Claude Code with orchestrator prompt."""
|
|
3591
3869
|
import textwrap
|
|
@@ -3605,8 +3883,13 @@ def cmd_claude(args: argparse.Namespace) -> None:
|
|
|
3605
3883
|
|
|
3606
3884
|
try:
|
|
3607
3885
|
if args.init:
|
|
3886
|
+
# Install/upgrade plugin first
|
|
3887
|
+
install_htmlgraph_plugin(args)
|
|
3888
|
+
|
|
3608
3889
|
# Load optimized orchestrator system prompt
|
|
3609
|
-
prompt_file =
|
|
3890
|
+
prompt_file = (
|
|
3891
|
+
Path(__file__).parent / "orchestrator-system-prompt-optimized.txt"
|
|
3892
|
+
)
|
|
3610
3893
|
|
|
3611
3894
|
if prompt_file.exists():
|
|
3612
3895
|
system_prompt = prompt_file.read_text(encoding="utf-8")
|
|
@@ -3670,6 +3953,9 @@ def cmd_claude(args: argparse.Namespace) -> None:
|
|
|
3670
3953
|
sys.exit(1)
|
|
3671
3954
|
|
|
3672
3955
|
elif args.continue_session:
|
|
3956
|
+
# Install/upgrade plugin first
|
|
3957
|
+
install_htmlgraph_plugin(args)
|
|
3958
|
+
|
|
3673
3959
|
# Resume last Claude Code session
|
|
3674
3960
|
# Find plugin directory relative to project root
|
|
3675
3961
|
plugin_dir = (
|
|
@@ -3726,22 +4012,69 @@ def cmd_claude(args: argparse.Namespace) -> None:
|
|
|
3726
4012
|
)
|
|
3727
4013
|
sys.exit(1)
|
|
3728
4014
|
|
|
4015
|
+
# Load optimized orchestrator system prompt
|
|
4016
|
+
prompt_file = (
|
|
4017
|
+
Path(__file__).parent / "orchestrator-system-prompt-optimized.txt"
|
|
4018
|
+
)
|
|
4019
|
+
|
|
4020
|
+
if prompt_file.exists():
|
|
4021
|
+
system_prompt = prompt_file.read_text(encoding="utf-8")
|
|
4022
|
+
else:
|
|
4023
|
+
# Fallback: provide minimal orchestrator guidance
|
|
4024
|
+
system_prompt = textwrap.dedent(
|
|
4025
|
+
"""
|
|
4026
|
+
You are an AI orchestrator for HtmlGraph project development.
|
|
4027
|
+
|
|
4028
|
+
CRITICAL DIRECTIVES:
|
|
4029
|
+
1. DELEGATE to subagents - do not implement directly
|
|
4030
|
+
2. CREATE work items before delegating (features, bugs, spikes)
|
|
4031
|
+
3. USE SDK for tracking - all work must be tracked in .htmlgraph/
|
|
4032
|
+
4. RESPECT dependencies - check blockers before starting
|
|
4033
|
+
|
|
4034
|
+
Key Rules:
|
|
4035
|
+
- Implementation work → delegate to general-purpose subagent
|
|
4036
|
+
- Research/exploration → delegate to explorer subagent
|
|
4037
|
+
- Testing/validation → delegate to test-runner subagent
|
|
4038
|
+
- Complex analysis → delegate to appropriate specialist
|
|
4039
|
+
|
|
4040
|
+
Always use:
|
|
4041
|
+
from htmlgraph import SDK
|
|
4042
|
+
sdk = SDK(agent='orchestrator')
|
|
4043
|
+
|
|
4044
|
+
See CLAUDE.md for complete orchestrator directives.
|
|
4045
|
+
"""
|
|
4046
|
+
)
|
|
4047
|
+
|
|
4048
|
+
# Combine orchestrator prompt with orchestration rules
|
|
4049
|
+
combined_prompt = system_prompt
|
|
4050
|
+
if orchestration_rules:
|
|
4051
|
+
combined_prompt = f"{system_prompt}\n\n---\n\n{orchestration_rules}"
|
|
4052
|
+
|
|
3729
4053
|
if args.quiet or args.format == "json":
|
|
3730
|
-
cmd = [
|
|
4054
|
+
cmd = [
|
|
4055
|
+
"claude",
|
|
4056
|
+
"--plugin-dir",
|
|
4057
|
+
str(plugin_dir),
|
|
4058
|
+
"--append-system-prompt",
|
|
4059
|
+
combined_prompt,
|
|
4060
|
+
]
|
|
3731
4061
|
else:
|
|
3732
4062
|
print("=" * 60)
|
|
3733
4063
|
print("🔧 HtmlGraph Development Mode")
|
|
3734
4064
|
print("=" * 60)
|
|
3735
4065
|
print(f"\nLoading plugin from: {plugin_dir}")
|
|
3736
4066
|
print(" ✓ Skills, agents, and hooks will be loaded from local files")
|
|
4067
|
+
print(" ✓ Orchestrator system prompt will be appended")
|
|
3737
4068
|
print(" ✓ Multi-AI delegation rules will be injected")
|
|
3738
4069
|
print(" ✓ Changes to plugin files will take effect after restart")
|
|
3739
4070
|
print()
|
|
3740
|
-
cmd = [
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
4071
|
+
cmd = [
|
|
4072
|
+
"claude",
|
|
4073
|
+
"--plugin-dir",
|
|
4074
|
+
str(plugin_dir),
|
|
4075
|
+
"--append-system-prompt",
|
|
4076
|
+
combined_prompt,
|
|
4077
|
+
]
|
|
3745
4078
|
|
|
3746
4079
|
try:
|
|
3747
4080
|
subprocess.run(cmd, check=False)
|
|
@@ -5177,6 +5510,61 @@ For more help: https://github.com/Shakes-tzd/htmlgraph
|
|
|
5177
5510
|
"--graph-dir", "-g", default=".htmlgraph", help="Graph directory"
|
|
5178
5511
|
)
|
|
5179
5512
|
|
|
5513
|
+
# orchestrator acknowledge-violation
|
|
5514
|
+
orchestrator_acknowledge_violation = orchestrator_subparsers.add_parser(
|
|
5515
|
+
"acknowledge-violation",
|
|
5516
|
+
help="Acknowledge circuit breaker violation and reset state",
|
|
5517
|
+
)
|
|
5518
|
+
orchestrator_acknowledge_violation.add_argument(
|
|
5519
|
+
"--graph-dir", "-g", default=".htmlgraph", help="Graph directory"
|
|
5520
|
+
)
|
|
5521
|
+
|
|
5522
|
+
# cigs (Computational Imperative Guidance System) with subcommands
|
|
5523
|
+
cigs_parser = subparsers.add_parser(
|
|
5524
|
+
"cigs", help="CIGS (Computational Imperative Guidance System) management"
|
|
5525
|
+
)
|
|
5526
|
+
cigs_subparsers = cigs_parser.add_subparsers(
|
|
5527
|
+
dest="cigs_command", help="CIGS command"
|
|
5528
|
+
)
|
|
5529
|
+
|
|
5530
|
+
# cigs status
|
|
5531
|
+
cigs_status = cigs_subparsers.add_parser(
|
|
5532
|
+
"status", help="Show current session CIGS status"
|
|
5533
|
+
)
|
|
5534
|
+
cigs_status.add_argument(
|
|
5535
|
+
"--graph-dir", "-g", default=".htmlgraph", help="Graph directory"
|
|
5536
|
+
)
|
|
5537
|
+
|
|
5538
|
+
# cigs summary
|
|
5539
|
+
cigs_summary = cigs_subparsers.add_parser(
|
|
5540
|
+
"summary", help="Show detailed session summary"
|
|
5541
|
+
)
|
|
5542
|
+
cigs_summary.add_argument(
|
|
5543
|
+
"--session-id", "-s", help="Session ID (defaults to current session)"
|
|
5544
|
+
)
|
|
5545
|
+
cigs_summary.add_argument(
|
|
5546
|
+
"--graph-dir", "-g", default=".htmlgraph", help="Graph directory"
|
|
5547
|
+
)
|
|
5548
|
+
|
|
5549
|
+
# cigs patterns
|
|
5550
|
+
cigs_patterns = cigs_subparsers.add_parser(
|
|
5551
|
+
"patterns", help="List all detected patterns"
|
|
5552
|
+
)
|
|
5553
|
+
cigs_patterns.add_argument(
|
|
5554
|
+
"--graph-dir", "-g", default=".htmlgraph", help="Graph directory"
|
|
5555
|
+
)
|
|
5556
|
+
|
|
5557
|
+
# cigs reset-violations
|
|
5558
|
+
cigs_reset_violations = cigs_subparsers.add_parser(
|
|
5559
|
+
"reset-violations", help="Reset violation count for current session"
|
|
5560
|
+
)
|
|
5561
|
+
cigs_reset_violations.add_argument(
|
|
5562
|
+
"--yes", "-y", action="store_true", help="Skip confirmation prompt"
|
|
5563
|
+
)
|
|
5564
|
+
cigs_reset_violations.add_argument(
|
|
5565
|
+
"--graph-dir", "-g", default=".htmlgraph", help="Graph directory"
|
|
5566
|
+
)
|
|
5567
|
+
|
|
5180
5568
|
# install-gemini-extension
|
|
5181
5569
|
subparsers.add_parser(
|
|
5182
5570
|
"install-gemini-extension",
|
|
@@ -5438,9 +5826,23 @@ For more help: https://github.com/Shakes-tzd/htmlgraph
|
|
|
5438
5826
|
cmd_orchestrator_set_level(args)
|
|
5439
5827
|
elif args.orchestrator_command == "reset-violations":
|
|
5440
5828
|
cmd_orchestrator_reset_violations(args)
|
|
5829
|
+
elif args.orchestrator_command == "acknowledge-violation":
|
|
5830
|
+
cmd_orchestrator_acknowledge_violation(args)
|
|
5441
5831
|
else:
|
|
5442
5832
|
orchestrator_parser.print_help()
|
|
5443
5833
|
sys.exit(1)
|
|
5834
|
+
elif args.command == "cigs":
|
|
5835
|
+
if args.cigs_command == "status":
|
|
5836
|
+
cmd_cigs_status(args)
|
|
5837
|
+
elif args.cigs_command == "summary":
|
|
5838
|
+
cmd_cigs_summary(args)
|
|
5839
|
+
elif args.cigs_command == "patterns":
|
|
5840
|
+
cmd_cigs_patterns(args)
|
|
5841
|
+
elif args.cigs_command == "reset-violations":
|
|
5842
|
+
cmd_cigs_reset_violations(args)
|
|
5843
|
+
else:
|
|
5844
|
+
cigs_parser.print_help()
|
|
5845
|
+
sys.exit(1)
|
|
5444
5846
|
elif args.command == "install-gemini-extension":
|
|
5445
5847
|
cmd_install_gemini_extension(args)
|
|
5446
5848
|
elif args.command == "claude":
|