@jaguilar87/gaia-ops 4.4.0 → 4.7.2
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +12 -3
- package/ARCHITECTURE.md +9 -8
- package/CHANGELOG.md +34 -0
- package/README.md +43 -11
- package/agents/terraform-architect.md +1 -1
- package/bin/README.md +2 -2
- package/bin/gaia-doctor.js +18 -5
- package/bin/gaia-history.js +0 -1
- package/bin/gaia-metrics.js +2 -2
- package/bin/gaia-scan.py +23 -1
- package/bin/gaia-update.js +346 -54
- package/bin/pre-publish-validate.js +33 -10
- package/commands/gaia.md +37 -0
- package/config/README.md +3 -9
- package/config/context-contracts.json +47 -15
- package/config/surface-routing.json +9 -1
- package/dist/gaia-ops/.claude-plugin/plugin.json +22 -0
- package/dist/gaia-ops/agents/cloud-troubleshooter.md +73 -0
- package/dist/gaia-ops/agents/devops-developer.md +57 -0
- package/dist/gaia-ops/agents/gaia-system.md +58 -0
- package/dist/gaia-ops/agents/gitops-operator.md +60 -0
- package/dist/gaia-ops/agents/speckit-planner.md +71 -0
- package/dist/gaia-ops/agents/terraform-architect.md +60 -0
- package/dist/gaia-ops/commands/gaia.md +37 -0
- package/dist/gaia-ops/config/README.md +58 -0
- package/dist/gaia-ops/config/cloud/aws.json +140 -0
- package/dist/gaia-ops/config/cloud/gcp.json +145 -0
- package/dist/gaia-ops/config/context-contracts.json +131 -0
- package/dist/gaia-ops/config/git_standards.json +72 -0
- package/dist/gaia-ops/config/surface-routing.json +197 -0
- package/dist/gaia-ops/config/universal-rules.json +10 -0
- package/dist/gaia-ops/hooks/adapters/__init__.py +52 -0
- package/dist/gaia-ops/hooks/adapters/base.py +219 -0
- package/dist/gaia-ops/hooks/adapters/channel.py +17 -0
- package/dist/gaia-ops/hooks/adapters/claude_code.py +1477 -0
- package/dist/gaia-ops/hooks/adapters/types.py +194 -0
- package/dist/gaia-ops/hooks/adapters/utils.py +25 -0
- package/dist/gaia-ops/hooks/hooks.json +126 -0
- package/dist/gaia-ops/hooks/modules/__init__.py +15 -0
- package/dist/gaia-ops/hooks/modules/agents/__init__.py +29 -0
- package/dist/gaia-ops/hooks/modules/agents/contract_validator.py +647 -0
- package/dist/gaia-ops/hooks/modules/agents/response_contract.py +496 -0
- package/dist/gaia-ops/hooks/modules/agents/skill_injection_verifier.py +124 -0
- package/dist/gaia-ops/hooks/modules/agents/task_info_builder.py +74 -0
- package/dist/gaia-ops/hooks/modules/agents/transcript_analyzer.py +458 -0
- package/dist/gaia-ops/hooks/modules/agents/transcript_reader.py +152 -0
- package/dist/gaia-ops/hooks/modules/audit/__init__.py +28 -0
- package/dist/gaia-ops/hooks/modules/audit/event_detector.py +168 -0
- package/dist/gaia-ops/hooks/modules/audit/logger.py +131 -0
- package/dist/gaia-ops/hooks/modules/audit/metrics.py +134 -0
- package/dist/gaia-ops/hooks/modules/audit/workflow_auditor.py +576 -0
- package/dist/gaia-ops/hooks/modules/audit/workflow_recorder.py +296 -0
- package/dist/gaia-ops/hooks/modules/context/__init__.py +11 -0
- package/dist/gaia-ops/hooks/modules/context/anchor_tracker.py +317 -0
- package/dist/gaia-ops/hooks/modules/context/compact_context_builder.py +215 -0
- package/dist/gaia-ops/hooks/modules/context/context_cache.py +129 -0
- package/dist/gaia-ops/hooks/modules/context/context_freshness.py +145 -0
- package/dist/gaia-ops/hooks/modules/context/context_injector.py +427 -0
- package/dist/gaia-ops/hooks/modules/context/context_writer.py +518 -0
- package/dist/gaia-ops/hooks/modules/context/contracts_loader.py +161 -0
- package/dist/gaia-ops/hooks/modules/core/__init__.py +40 -0
- package/dist/gaia-ops/hooks/modules/core/hook_entry.py +78 -0
- package/dist/gaia-ops/hooks/modules/core/paths.py +160 -0
- package/dist/gaia-ops/hooks/modules/core/plugin_mode.py +149 -0
- package/dist/gaia-ops/hooks/modules/core/plugin_setup.py +558 -0
- package/dist/gaia-ops/hooks/modules/core/state.py +179 -0
- package/dist/gaia-ops/hooks/modules/core/stdin.py +24 -0
- package/dist/gaia-ops/hooks/modules/events/__init__.py +1 -0
- package/dist/gaia-ops/hooks/modules/events/event_writer.py +210 -0
- package/dist/gaia-ops/hooks/modules/identity/__init__.py +0 -0
- package/dist/gaia-ops/hooks/modules/identity/identity_provider.py +21 -0
- package/dist/gaia-ops/hooks/modules/identity/ops_identity.py +34 -0
- package/dist/gaia-ops/hooks/modules/identity/security_identity.py +10 -0
- package/dist/gaia-ops/hooks/modules/memory/__init__.py +8 -0
- package/dist/gaia-ops/hooks/modules/memory/episode_writer.py +227 -0
- package/dist/gaia-ops/hooks/modules/orchestrator/__init__.py +1 -0
- package/dist/gaia-ops/hooks/modules/orchestrator/delegate_mode.py +128 -0
- package/dist/gaia-ops/hooks/modules/scanning/__init__.py +8 -0
- package/dist/gaia-ops/hooks/modules/scanning/scan_trigger.py +84 -0
- package/dist/gaia-ops/hooks/modules/security/__init__.py +89 -0
- package/dist/gaia-ops/hooks/modules/security/approval_cleanup.py +87 -0
- package/dist/gaia-ops/hooks/modules/security/approval_constants.py +23 -0
- package/dist/gaia-ops/hooks/modules/security/approval_grants.py +912 -0
- package/dist/gaia-ops/hooks/modules/security/approval_messages.py +71 -0
- package/dist/gaia-ops/hooks/modules/security/approval_scopes.py +153 -0
- package/dist/gaia-ops/hooks/modules/security/blocked_commands.py +584 -0
- package/dist/gaia-ops/hooks/modules/security/blocked_message_formatter.py +86 -0
- package/dist/gaia-ops/hooks/modules/security/command_semantics.py +130 -0
- package/dist/gaia-ops/hooks/modules/security/gitops_validator.py +179 -0
- package/dist/gaia-ops/hooks/modules/security/mutative_verbs.py +850 -0
- package/dist/gaia-ops/hooks/modules/security/prompt_validator.py +40 -0
- package/dist/gaia-ops/hooks/modules/security/tiers.py +196 -0
- package/dist/gaia-ops/hooks/modules/session/__init__.py +10 -0
- package/dist/gaia-ops/hooks/modules/session/session_context_writer.py +100 -0
- package/dist/gaia-ops/hooks/modules/session/session_event_injector.py +158 -0
- package/dist/gaia-ops/hooks/modules/session/session_manager.py +31 -0
- package/dist/gaia-ops/hooks/modules/tools/__init__.py +25 -0
- package/dist/gaia-ops/hooks/modules/tools/bash_validator.py +708 -0
- package/dist/gaia-ops/hooks/modules/tools/cloud_pipe_validator.py +181 -0
- package/dist/gaia-ops/hooks/modules/tools/hook_response.py +55 -0
- package/dist/gaia-ops/hooks/modules/tools/shell_parser.py +227 -0
- package/dist/gaia-ops/hooks/modules/tools/task_validator.py +283 -0
- package/dist/gaia-ops/hooks/modules/validation/__init__.py +23 -0
- package/dist/gaia-ops/hooks/modules/validation/commit_validator.py +380 -0
- package/dist/gaia-ops/hooks/post_compact.py +43 -0
- package/dist/gaia-ops/hooks/post_tool_use.py +54 -0
- package/dist/gaia-ops/hooks/pre_tool_use.py +383 -0
- package/dist/gaia-ops/hooks/session_start.py +69 -0
- package/dist/gaia-ops/hooks/stop_hook.py +69 -0
- package/dist/gaia-ops/hooks/subagent_start.py +71 -0
- package/dist/gaia-ops/hooks/subagent_stop.py +288 -0
- package/dist/gaia-ops/hooks/task_completed.py +70 -0
- package/dist/gaia-ops/hooks/user_prompt_submit.py +177 -0
- package/dist/gaia-ops/settings.json +72 -0
- package/dist/gaia-ops/skills/README.md +109 -0
- package/dist/gaia-ops/skills/agent-protocol/SKILL.md +105 -0
- package/dist/gaia-ops/skills/agent-protocol/examples.md +170 -0
- package/dist/gaia-ops/skills/agent-response/SKILL.md +53 -0
- package/dist/gaia-ops/skills/approval/SKILL.md +85 -0
- package/dist/gaia-ops/skills/approval/examples.md +140 -0
- package/dist/gaia-ops/skills/approval/reference.md +57 -0
- package/dist/gaia-ops/skills/command-execution/SKILL.md +64 -0
- package/dist/gaia-ops/skills/command-execution/reference.md +83 -0
- package/dist/gaia-ops/skills/context-updater/SKILL.md +76 -0
- package/dist/gaia-ops/skills/context-updater/examples.md +71 -0
- package/dist/gaia-ops/skills/developer-patterns/SKILL.md +93 -0
- package/dist/gaia-ops/skills/developer-patterns/reference.md +112 -0
- package/dist/gaia-ops/skills/execution/SKILL.md +66 -0
- package/dist/gaia-ops/skills/fast-queries/SKILL.md +47 -0
- package/dist/gaia-ops/skills/gaia-patterns/SKILL.md +92 -0
- package/dist/gaia-ops/skills/gaia-patterns/reference.md +22 -0
- package/dist/gaia-ops/skills/git-conventions/SKILL.md +48 -0
- package/dist/gaia-ops/skills/gitops-patterns/SKILL.md +73 -0
- package/dist/gaia-ops/skills/gitops-patterns/reference.md +183 -0
- package/dist/gaia-ops/skills/investigation/SKILL.md +77 -0
- package/dist/gaia-ops/skills/orchestrator-approval/SKILL.md +64 -0
- package/dist/gaia-ops/skills/reference.md +134 -0
- package/dist/gaia-ops/skills/security-tiers/SKILL.md +61 -0
- package/dist/gaia-ops/skills/security-tiers/destructive-commands-reference.md +623 -0
- package/dist/gaia-ops/skills/security-tiers/reference.md +39 -0
- package/dist/gaia-ops/skills/skill-creation/SKILL.md +119 -0
- package/dist/gaia-ops/skills/specification/SKILL.md +186 -0
- package/dist/gaia-ops/skills/speckit-workflow/SKILL.md +165 -0
- package/dist/gaia-ops/skills/speckit-workflow/reference.md +117 -0
- package/dist/gaia-ops/skills/terraform-patterns/SKILL.md +63 -0
- package/dist/gaia-ops/skills/terraform-patterns/reference.md +93 -0
- package/dist/gaia-ops/speckit/README.md +516 -0
- package/dist/gaia-ops/speckit/scripts/.gitkeep +0 -0
- package/dist/gaia-ops/speckit/templates/adr-template.md +118 -0
- package/dist/gaia-ops/speckit/templates/agent-file-template.md +23 -0
- package/dist/gaia-ops/speckit/templates/plan-template.md +227 -0
- package/dist/gaia-ops/speckit/templates/spec-template.md +140 -0
- package/dist/gaia-ops/speckit/templates/tasks-template.md +257 -0
- package/dist/gaia-ops/tools/context/README.md +132 -0
- package/dist/gaia-ops/tools/context/__init__.py +42 -0
- package/dist/gaia-ops/tools/context/_paths.py +20 -0
- package/dist/gaia-ops/tools/context/context_provider.py +476 -0
- package/dist/gaia-ops/tools/context/context_section_reader.py +330 -0
- package/dist/gaia-ops/tools/context/deep_merge.py +159 -0
- package/dist/gaia-ops/tools/context/pending_updates.py +760 -0
- package/dist/gaia-ops/tools/context/surface_router.py +278 -0
- package/dist/gaia-ops/tools/fast-queries/README.md +65 -0
- package/dist/gaia-ops/tools/fast-queries/__init__.py +30 -0
- package/dist/gaia-ops/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
- package/dist/gaia-ops/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
- package/dist/gaia-ops/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
- package/dist/gaia-ops/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
- package/dist/gaia-ops/tools/fast-queries/run_triage.sh +59 -0
- package/dist/gaia-ops/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
- package/dist/gaia-ops/tools/gaia_simulator/__init__.py +33 -0
- package/dist/gaia-ops/tools/gaia_simulator/cli.py +354 -0
- package/dist/gaia-ops/tools/gaia_simulator/extractor.py +457 -0
- package/dist/gaia-ops/tools/gaia_simulator/reporter.py +258 -0
- package/dist/gaia-ops/tools/gaia_simulator/routing_simulator.py +334 -0
- package/dist/gaia-ops/tools/gaia_simulator/runner.py +539 -0
- package/dist/gaia-ops/tools/gaia_simulator/skills_mapper.py +262 -0
- package/dist/gaia-ops/tools/memory/README.md +0 -0
- package/dist/gaia-ops/tools/memory/__init__.py +20 -0
- package/dist/gaia-ops/tools/memory/episodic.py +1196 -0
- package/dist/gaia-ops/tools/persist_transcript_analysis.py +85 -0
- package/dist/gaia-ops/tools/review/__init__.py +1 -0
- package/dist/gaia-ops/tools/review/review_engine.py +157 -0
- package/dist/gaia-ops/tools/scan/__init__.py +35 -0
- package/dist/gaia-ops/tools/scan/config.py +247 -0
- package/dist/gaia-ops/tools/scan/merge.py +212 -0
- package/dist/gaia-ops/tools/scan/orchestrator.py +549 -0
- package/dist/gaia-ops/tools/scan/registry.py +127 -0
- package/dist/gaia-ops/tools/scan/scanners/__init__.py +18 -0
- package/dist/gaia-ops/tools/scan/scanners/base.py +137 -0
- package/dist/gaia-ops/tools/scan/scanners/environment.py +324 -0
- package/dist/gaia-ops/tools/scan/scanners/git.py +570 -0
- package/dist/gaia-ops/tools/scan/scanners/infrastructure.py +875 -0
- package/dist/gaia-ops/tools/scan/scanners/orchestration.py +600 -0
- package/dist/gaia-ops/tools/scan/scanners/stack.py +1085 -0
- package/dist/gaia-ops/tools/scan/scanners/tools.py +260 -0
- package/dist/gaia-ops/tools/scan/setup.py +753 -0
- package/dist/gaia-ops/tools/scan/tests/__init__.py +1 -0
- package/dist/gaia-ops/tools/scan/tests/conftest.py +796 -0
- package/dist/gaia-ops/tools/scan/tests/test_environment.py +323 -0
- package/dist/gaia-ops/tools/scan/tests/test_git.py +419 -0
- package/dist/gaia-ops/tools/scan/tests/test_infrastructure.py +382 -0
- package/dist/gaia-ops/tools/scan/tests/test_integration.py +920 -0
- package/dist/gaia-ops/tools/scan/tests/test_merge.py +269 -0
- package/dist/gaia-ops/tools/scan/tests/test_orchestration.py +304 -0
- package/dist/gaia-ops/tools/scan/tests/test_stack.py +604 -0
- package/dist/gaia-ops/tools/scan/tests/test_tools.py +349 -0
- package/dist/gaia-ops/tools/scan/ui.py +624 -0
- package/dist/gaia-ops/tools/scan/verify.py +266 -0
- package/dist/gaia-ops/tools/scan/walk.py +118 -0
- package/dist/gaia-ops/tools/scan/workspace.py +85 -0
- package/dist/gaia-ops/tools/validation/README.md +244 -0
- package/dist/gaia-ops/tools/validation/__init__.py +17 -0
- package/dist/gaia-ops/tools/validation/approval_gate.py +321 -0
- package/dist/gaia-ops/tools/validation/validate_skills.py +189 -0
- package/dist/gaia-security/.claude-plugin/plugin.json +22 -0
- package/dist/gaia-security/config/universal-rules.json +10 -0
- package/dist/gaia-security/hooks/adapters/__init__.py +52 -0
- package/dist/gaia-security/hooks/adapters/base.py +219 -0
- package/dist/gaia-security/hooks/adapters/channel.py +17 -0
- package/dist/gaia-security/hooks/adapters/claude_code.py +1477 -0
- package/dist/gaia-security/hooks/adapters/types.py +194 -0
- package/dist/gaia-security/hooks/adapters/utils.py +25 -0
- package/dist/gaia-security/hooks/hooks.json +57 -0
- package/dist/gaia-security/hooks/modules/__init__.py +15 -0
- package/dist/gaia-security/hooks/modules/agents/__init__.py +29 -0
- package/dist/gaia-security/hooks/modules/agents/contract_validator.py +647 -0
- package/dist/gaia-security/hooks/modules/agents/response_contract.py +496 -0
- package/dist/gaia-security/hooks/modules/agents/skill_injection_verifier.py +124 -0
- package/dist/gaia-security/hooks/modules/agents/task_info_builder.py +74 -0
- package/dist/gaia-security/hooks/modules/agents/transcript_analyzer.py +458 -0
- package/dist/gaia-security/hooks/modules/agents/transcript_reader.py +152 -0
- package/dist/gaia-security/hooks/modules/audit/__init__.py +28 -0
- package/dist/gaia-security/hooks/modules/audit/event_detector.py +168 -0
- package/dist/gaia-security/hooks/modules/audit/logger.py +131 -0
- package/dist/gaia-security/hooks/modules/audit/metrics.py +134 -0
- package/dist/gaia-security/hooks/modules/audit/workflow_auditor.py +576 -0
- package/dist/gaia-security/hooks/modules/audit/workflow_recorder.py +296 -0
- package/dist/gaia-security/hooks/modules/context/__init__.py +11 -0
- package/dist/gaia-security/hooks/modules/context/anchor_tracker.py +317 -0
- package/dist/gaia-security/hooks/modules/context/compact_context_builder.py +215 -0
- package/dist/gaia-security/hooks/modules/context/context_cache.py +129 -0
- package/dist/gaia-security/hooks/modules/context/context_freshness.py +145 -0
- package/dist/gaia-security/hooks/modules/context/context_injector.py +427 -0
- package/dist/gaia-security/hooks/modules/context/context_writer.py +518 -0
- package/dist/gaia-security/hooks/modules/context/contracts_loader.py +161 -0
- package/dist/gaia-security/hooks/modules/core/__init__.py +40 -0
- package/dist/gaia-security/hooks/modules/core/hook_entry.py +78 -0
- package/dist/gaia-security/hooks/modules/core/paths.py +160 -0
- package/dist/gaia-security/hooks/modules/core/plugin_mode.py +149 -0
- package/dist/gaia-security/hooks/modules/core/plugin_setup.py +558 -0
- package/dist/gaia-security/hooks/modules/core/state.py +179 -0
- package/dist/gaia-security/hooks/modules/core/stdin.py +24 -0
- package/dist/gaia-security/hooks/modules/events/__init__.py +1 -0
- package/dist/gaia-security/hooks/modules/events/event_writer.py +210 -0
- package/dist/gaia-security/hooks/modules/identity/__init__.py +0 -0
- package/dist/gaia-security/hooks/modules/identity/identity_provider.py +21 -0
- package/dist/gaia-security/hooks/modules/identity/ops_identity.py +34 -0
- package/dist/gaia-security/hooks/modules/identity/security_identity.py +10 -0
- package/dist/gaia-security/hooks/modules/memory/__init__.py +8 -0
- package/dist/gaia-security/hooks/modules/memory/episode_writer.py +227 -0
- package/dist/gaia-security/hooks/modules/orchestrator/__init__.py +1 -0
- package/dist/gaia-security/hooks/modules/orchestrator/delegate_mode.py +128 -0
- package/dist/gaia-security/hooks/modules/scanning/__init__.py +8 -0
- package/dist/gaia-security/hooks/modules/scanning/scan_trigger.py +84 -0
- package/dist/gaia-security/hooks/modules/security/__init__.py +89 -0
- package/dist/gaia-security/hooks/modules/security/approval_cleanup.py +87 -0
- package/dist/gaia-security/hooks/modules/security/approval_constants.py +23 -0
- package/dist/gaia-security/hooks/modules/security/approval_grants.py +912 -0
- package/dist/gaia-security/hooks/modules/security/approval_messages.py +71 -0
- package/dist/gaia-security/hooks/modules/security/approval_scopes.py +153 -0
- package/dist/gaia-security/hooks/modules/security/blocked_commands.py +584 -0
- package/dist/gaia-security/hooks/modules/security/blocked_message_formatter.py +86 -0
- package/dist/gaia-security/hooks/modules/security/command_semantics.py +130 -0
- package/dist/gaia-security/hooks/modules/security/gitops_validator.py +179 -0
- package/dist/gaia-security/hooks/modules/security/mutative_verbs.py +850 -0
- package/dist/gaia-security/hooks/modules/security/prompt_validator.py +40 -0
- package/dist/gaia-security/hooks/modules/security/tiers.py +196 -0
- package/dist/gaia-security/hooks/modules/session/__init__.py +10 -0
- package/dist/gaia-security/hooks/modules/session/session_context_writer.py +100 -0
- package/dist/gaia-security/hooks/modules/session/session_event_injector.py +158 -0
- package/dist/gaia-security/hooks/modules/session/session_manager.py +31 -0
- package/dist/gaia-security/hooks/modules/tools/__init__.py +25 -0
- package/dist/gaia-security/hooks/modules/tools/bash_validator.py +708 -0
- package/dist/gaia-security/hooks/modules/tools/cloud_pipe_validator.py +181 -0
- package/dist/gaia-security/hooks/modules/tools/hook_response.py +55 -0
- package/dist/gaia-security/hooks/modules/tools/shell_parser.py +227 -0
- package/dist/gaia-security/hooks/modules/tools/task_validator.py +283 -0
- package/dist/gaia-security/hooks/modules/validation/__init__.py +23 -0
- package/dist/gaia-security/hooks/modules/validation/commit_validator.py +380 -0
- package/dist/gaia-security/hooks/post_tool_use.py +54 -0
- package/dist/gaia-security/hooks/pre_tool_use.py +383 -0
- package/dist/gaia-security/hooks/session_start.py +69 -0
- package/dist/gaia-security/hooks/stop_hook.py +69 -0
- package/dist/gaia-security/hooks/user_prompt_submit.py +177 -0
- package/dist/gaia-security/settings.json +58 -0
- package/git-hooks/commit-msg +41 -0
- package/hooks/README.md +8 -6
- package/hooks/adapters/channel.py +0 -25
- package/hooks/adapters/claude_code.py +364 -125
- package/hooks/elicitation_result.py +132 -0
- package/hooks/hooks.json +10 -1
- package/hooks/modules/README.md +3 -2
- package/hooks/modules/agents/contract_validator.py +3 -51
- package/hooks/modules/agents/response_contract.py +4 -8
- package/hooks/modules/agents/transcript_reader.py +4 -5
- package/hooks/modules/audit/__init__.py +4 -6
- package/hooks/modules/audit/event_detector.py +0 -2
- package/hooks/modules/audit/metrics.py +108 -187
- package/hooks/modules/audit/workflow_auditor.py +0 -4
- package/hooks/modules/audit/workflow_recorder.py +0 -5
- package/hooks/modules/context/compact_context_builder.py +1 -0
- package/hooks/modules/context/context_cache.py +129 -0
- package/hooks/modules/context/context_injector.py +18 -40
- package/hooks/modules/context/context_writer.py +1 -25
- package/hooks/modules/context/contracts_loader.py +7 -10
- package/hooks/modules/core/hook_entry.py +1 -0
- package/hooks/modules/core/paths.py +12 -13
- package/hooks/modules/core/plugin_mode.py +74 -4
- package/hooks/modules/core/plugin_setup.py +395 -23
- package/hooks/modules/events/__init__.py +1 -0
- package/hooks/modules/events/event_writer.py +210 -0
- package/hooks/modules/identity/ops_identity.py +18 -27
- package/hooks/modules/memory/episode_writer.py +1 -6
- package/hooks/modules/orchestrator/__init__.py +1 -0
- package/hooks/modules/orchestrator/delegate_mode.py +128 -0
- package/hooks/modules/security/__init__.py +2 -4
- package/hooks/modules/security/approval_constants.py +5 -1
- package/hooks/modules/security/approval_grants.py +189 -6
- package/hooks/modules/security/approval_messages.py +9 -21
- package/hooks/modules/security/blocked_commands.py +98 -34
- package/hooks/modules/security/command_semantics.py +0 -4
- package/hooks/modules/security/gitops_validator.py +1 -11
- package/hooks/modules/security/mutative_verbs.py +179 -38
- package/hooks/modules/security/tiers.py +1 -19
- package/hooks/modules/session/session_event_injector.py +1 -25
- package/hooks/modules/tools/bash_validator.py +310 -94
- package/hooks/modules/tools/shell_parser.py +0 -1
- package/hooks/modules/tools/task_validator.py +9 -29
- package/hooks/post_tool_use.py +0 -72
- package/hooks/pre_tool_use.py +42 -102
- package/hooks/session_start.py +4 -2
- package/hooks/subagent_start.py +6 -2
- package/hooks/subagent_stop.py +1 -13
- package/hooks/user_prompt_submit.py +119 -37
- package/index.js +1 -1
- package/package.json +5 -3
- package/skills/README.md +3 -5
- package/skills/agent-protocol/SKILL.md +17 -16
- package/skills/agent-protocol/examples.md +6 -6
- package/skills/agent-response/SKILL.md +11 -14
- package/skills/approval/SKILL.md +28 -13
- package/skills/approval/reference.md +2 -2
- package/skills/execution/SKILL.md +1 -1
- package/skills/gaia-patterns/SKILL.md +2 -3
- package/skills/orchestrator-approval/SKILL.md +22 -50
- package/skills/security-tiers/SKILL.md +1 -1
- package/templates/README.md +9 -9
- package/templates/managed-settings.template.json +43 -0
- package/tools/gaia_simulator/runner.py +34 -1
- package/tools/scan/orchestrator.py +13 -0
- package/tools/scan/scanners/base.py +8 -0
- package/tools/scan/scanners/git.py +78 -0
- package/tools/scan/scanners/infrastructure.py +65 -0
- package/tools/scan/scanners/stack.py +110 -0
- package/tools/scan/setup.py +120 -13
- package/tools/scan/workspace.py +85 -0
- package/config/context-contracts.aws.json +0 -42
- package/config/context-contracts.gcp.json +0 -39
- package/skills/project-dispatch/SKILL.md +0 -34
- package/templates/settings.template.json +0 -226
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
{
|
|
9
9
|
"name": "gaia-security",
|
|
10
10
|
"description": "Keeps you in the loop only when it matters. Gaia Security analyzes every command and classifies it into risk tiers: read-only queries run freely, simulations and validations pass through, and state-changing operations (create, delete, apply, push) pause for your explicit approval before executing. Irreversible commands like dropping databases or deleting cloud infrastructure are permanently blocked.",
|
|
11
|
-
"version": "4.
|
|
11
|
+
"version": "4.7.2",
|
|
12
12
|
"source": "./dist/gaia-security"
|
|
13
13
|
}
|
|
14
14
|
]
|
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gaia-ops",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.2",
|
|
4
4
|
"description": "Security-first orchestrator with specialized agents, hooks, and governance for AI coding",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "jaguilar87"
|
|
7
7
|
},
|
|
8
8
|
"repository": "https://github.com/metraton/gaia-ops",
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"keywords": [
|
|
10
|
+
"keywords": [
|
|
11
|
+
"security",
|
|
12
|
+
"devops",
|
|
13
|
+
"orchestrator",
|
|
14
|
+
"governance"
|
|
15
|
+
],
|
|
11
16
|
"engines": {
|
|
12
17
|
"claude-code": ">=2.1.0"
|
|
13
18
|
},
|
|
14
|
-
"categories": [
|
|
19
|
+
"categories": [
|
|
20
|
+
"devops",
|
|
21
|
+
"security",
|
|
22
|
+
"orchestration"
|
|
23
|
+
]
|
|
15
24
|
}
|
package/ARCHITECTURE.md
CHANGED
|
@@ -25,7 +25,8 @@ User request
|
|
|
25
25
|
v
|
|
26
26
|
user_prompt_submit.py (UserPromptSubmit hook)
|
|
27
27
|
| Inject orchestrator identity via ops_identity.py
|
|
28
|
-
|
|
|
28
|
+
| Inject surface routing recommendation (deterministic)
|
|
29
|
+
| Skills loaded on-demand: agent-response
|
|
29
30
|
v
|
|
30
31
|
Orchestrator dispatches to agent
|
|
31
32
|
| Routes by surface classification
|
|
@@ -49,7 +50,7 @@ subagent_stop.py (SubagentStop hook)
|
|
|
49
50
|
v
|
|
50
51
|
Orchestrator processes json:contract (via agent-response skill)
|
|
51
52
|
| COMPLETE -> summarize to user
|
|
52
|
-
|
|
|
53
|
+
| REVIEW (with approval_id) -> get approval -> resume via SendMessage
|
|
53
54
|
| NEEDS_INPUT -> ask user -> resume via SendMessage
|
|
54
55
|
| BLOCKED -> report blocker
|
|
55
56
|
```
|
|
@@ -170,7 +171,7 @@ Nonce-based T3 approval lifecycle:
|
|
|
170
171
|
3. BashValidator generates 128-bit nonce via generate_nonce()
|
|
171
172
|
4. write_pending_approval() saves pending-{nonce}.json to .claude/cache/approvals/
|
|
172
173
|
5. Hook returns corrective deny (exit 0) with NONCE:{hex} in message
|
|
173
|
-
6. Agent includes NONCE:{hex} in
|
|
174
|
+
6. Agent includes NONCE:{hex} in REVIEW status to orchestrator
|
|
174
175
|
7. Orchestrator presents plan to user, asks for approval
|
|
175
176
|
8. User approves -> orchestrator resumes agent with "APPROVE:{nonce}"
|
|
176
177
|
9. pre_tool_use.py detects APPROVE: prefix, calls activate_pending_approval()
|
|
@@ -182,7 +183,7 @@ Nonce-based T3 approval lifecycle:
|
|
|
182
183
|
|
|
183
184
|
Every agent response must end with a `json:contract` block containing `agent_status`. The contract validator (`hooks/modules/agents/contract_validator.py`) enforces:
|
|
184
185
|
|
|
185
|
-
- **AGENT_STATUS**: PLAN_STATUS (from
|
|
186
|
+
- **AGENT_STATUS**: PLAN_STATUS (from 5 valid states: COMPLETE, NEEDS_INPUT, REVIEW, BLOCKED, IN_PROGRESS), PENDING_STEPS, NEXT_ACTION, AGENT_ID
|
|
186
187
|
- **EVIDENCE_REPORT**: required for all valid states. Seven fields: PATTERNS_CHECKED, FILES_CHECKED, COMMANDS_RUN, KEY_OUTPUTS, VERBATIM_OUTPUTS, CROSS_LAYER_IMPACTS, OPEN_GAPS
|
|
187
188
|
- **CONSOLIDATION_REPORT**: required when multi-surface or cross-check. Fields: OWNERSHIP_ASSESSMENT (enum), CONFIRMED_FINDINGS, SUSPECTED_FINDINGS, CONFLICTS, OPEN_GAPS, NEXT_BEST_AGENT
|
|
188
189
|
|
|
@@ -256,12 +257,12 @@ The adapter layer connects Claude Code's hook protocol to gaia-ops business logi
|
|
|
256
257
|
| **Adapter methods called** | `ClaudeCodeAdapter.format_validation_response()` |
|
|
257
258
|
| **Business logic modules** | None (pure formatting bridge) |
|
|
258
259
|
|
|
259
|
-
### CP-5: `
|
|
260
|
+
### CP-5: `hooks/hooks.json` -- Hook Configuration
|
|
260
261
|
|
|
261
262
|
| Attribute | Value |
|
|
262
263
|
|-----------|-------|
|
|
263
|
-
| **File (npm channel)** | `templates/settings.template.json` -- paths use `.claude/hooks/` prefix |
|
|
264
264
|
| **File (plugin channel)** | `hooks/hooks.json` -- paths use `${CLAUDE_PLUGIN_ROOT}/hooks/` prefix |
|
|
265
|
+
| **File (npm channel)** | `hooks/hooks.json` (symlinked into `.claude/hooks/`) |
|
|
265
266
|
| **What it does** | Maps Claude Code hook events to handler scripts. Defines which events fire which entry points, the tool matchers (Bash, Task, Agent, `*`), and permissions (allow/deny lists). |
|
|
266
267
|
| **Events configured** | PreToolUse (Bash, Task, Agent, SendMessage), PostToolUse, SubagentStop, SessionStart, Stop, TaskCompleted, SubagentStart, UserPromptSubmit (identity injection) |
|
|
267
268
|
|
|
@@ -292,7 +293,7 @@ To add support for a new Claude Code hook event (e.g., a future `PreCompact` eve
|
|
|
292
293
|
2. **Add adapter method** to `ClaudeCodeAdapter` in `hooks/adapters/claude_code.py` -- implement `adapt_<event_name>(raw: dict) -> <ResultType>` and the corresponding `format_<result>_response()` if a new result type is needed.
|
|
293
294
|
3. **Add extract/format methods** for the event type -- the extract method pulls typed data from the raw payload, the format method builds the CLI response JSON.
|
|
294
295
|
4. **Create hook script entry point** -- a new `hooks/<event_name>.py` file that reads stdin, calls `adapter.parse_event()`, delegates to business logic, and writes the response to stdout.
|
|
295
|
-
5. **Add entry to `hooks/hooks.json`**
|
|
296
|
+
5. **Add entry to `hooks/hooks.json`** mapping the event name to the new script.
|
|
296
297
|
|
|
297
298
|
**Zero changes to business logic modules required.** The adapter is the only layer that touches CLI-specific JSON.
|
|
298
299
|
|
|
@@ -311,7 +312,7 @@ To support a CLI other than Claude Code (e.g., a hypothetical Cursor or Windsurf
|
|
|
311
312
|
| File | Purpose |
|
|
312
313
|
|------|---------|
|
|
313
314
|
| `hooks/modules/identity/ops_identity.py` | Orchestrator identity (injected by UserPromptSubmit) |
|
|
314
|
-
| `
|
|
315
|
+
| `config/surface-routing.json` | Surface routing config (agent table, signals, dispatch) |
|
|
315
316
|
| `skills/agent-response/SKILL.md` | Contract status handling protocol (on-demand) |
|
|
316
317
|
| `hooks/pre_tool_use.py` | PreToolUse hook entry point |
|
|
317
318
|
| `hooks/subagent_stop.py` | SubagentStop hook entry point |
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,40 @@ All notable changes to the gaia-ops orchestration system are documented in this
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [4.5.0] - 2026-03-24
|
|
9
|
+
|
|
10
|
+
### Settings Architecture Redesign + Multi-Cloud Security
|
|
11
|
+
|
|
12
|
+
Unified approach for permissions across NPM and plugin installation modes. Permissions now live in `settings.local.json` (union merge, preserves user config). `settings.json` contains only hooks.
|
|
13
|
+
|
|
14
|
+
#### Added
|
|
15
|
+
- **Azure deny rules** — 39 rules covering resource groups, networking, AKS, Key Vault, CosmosDB, Service Bus, and more
|
|
16
|
+
- **Generic wildcard deny rules** — 20 rules that catch all present and future cloud services (`aws * delete-*`, `az * delete`, `gcloud * delete`, etc.)
|
|
17
|
+
- **Indirect execution detection** — Catches `bash -c`, `eval`, `python3 -c`, `node -e`, `ruby -e`, `perl -e` wrappers that bypass regex patterns
|
|
18
|
+
- **Managed settings template** — `templates/managed-settings.template.json` for enterprise deployment via Claude.ai Admin Console
|
|
19
|
+
- **`updateLocalPermissions()`** in `gaia-update.js` — NPM postinstall now merges permissions into `settings.local.json` (same approach as plugin SessionStart)
|
|
20
|
+
- **Plugin mode detection via `plugin.json`** — `plugin_setup.py` and `plugin_mode.py` now read `.claude-plugin/plugin.json` for reliable name/version/mode detection with `--plugin-dir`
|
|
21
|
+
- **First-run welcome message** — `user_prompt_submit.py` detects first run and injects a welcome explaining that restart is needed to activate permissions
|
|
22
|
+
|
|
23
|
+
#### Changed
|
|
24
|
+
- **`settings.template.json`** — Removed permissions block; template now contains only hooks + environment
|
|
25
|
+
- **`_DENY_RULES` centralized in Python** — Single source of truth in `plugin_setup.py`, shared by both OPS and SECURITY modes
|
|
26
|
+
- **T3 approval flow** — All T3 mutative operations now use native `ask` dialog (both ops and security mode). Nonce workflow removed from direct conversation; kept for subagent use via skills.
|
|
27
|
+
- **`approval_messages.py`** — Simplified T3 block message to minimal data (tier + nonce). Workflow instructions live in skills, not hook messages.
|
|
28
|
+
- **`pre_tool_use.py`** — Simplified: passes through `block_response` from `bash_validator` directly, no more mode-specific branching
|
|
29
|
+
- **`bash_validator.py`** — T3 mutative returns `ask` response directly (no nonce generation, no pending files)
|
|
30
|
+
- **`session_start.py`** — Uses `mark_done=False` so `user_prompt_submit.py` can detect first-run and show welcome before marking initialized
|
|
31
|
+
- **`gaia-update.js` registry path** — Fixed to write `plugin-registry.json` in `.claude/` (same path Python hooks expect)
|
|
32
|
+
- **`gaia-doctor.js`** — Now checks permissions in `settings.local.json` (not just `settings.json`). Updated agent and config file lists.
|
|
33
|
+
- **`gaia-update.js` health check** — Updated config files (`surface-routing.json`) and agent list (`gaia-system.md`, `speckit-planner.md`)
|
|
34
|
+
|
|
35
|
+
#### Fixed
|
|
36
|
+
- **Registry path mismatch** — `gaia-update.js` wrote to `.claude/project-context/`, Python read from `.claude/`. Now both use `.claude/`.
|
|
37
|
+
- **Orphaned nonce files** — `bash_validator` no longer writes pending approval files for `ask` responses
|
|
38
|
+
- **Plugin mode detection** — `--plugin-dir` now correctly detects `gaia-ops` vs `gaia-security` via `plugin.json` instead of path parsing
|
|
39
|
+
- **First-run welcome race condition** — `SessionStart` no longer marks initialized; `UserPromptSubmit` marks after showing welcome
|
|
40
|
+
- **`_build_welcome()` framing** — Rewritten to explain WHY the user needs to restart (permissions not active yet), making Claude naturally relay the message
|
|
41
|
+
|
|
8
42
|
## [4.4.0-rc.5] - 2026-03-19
|
|
9
43
|
|
|
10
44
|
### Identity Redesign
|
package/README.md
CHANGED
|
@@ -14,14 +14,17 @@ Multi-agent DevOps system that classifies every operation by risk, routes work t
|
|
|
14
14
|
|
|
15
15
|
### Features
|
|
16
16
|
|
|
17
|
-
- **Multi-cloud support** - GCP, AWS
|
|
18
|
-
- **6 agents** - terraform-architect, gitops-operator, cloud-troubleshooter, devops-developer, speckit-planner, gaia (meta-agent)
|
|
17
|
+
- **Multi-cloud support** - GCP, AWS, Azure
|
|
18
|
+
- **6 agents** - terraform-architect, gitops-operator, cloud-troubleshooter, devops-developer, speckit-planner, gaia-system (meta-agent)
|
|
19
19
|
- **Contracts as SSOT** - Cloud-agnostic base contracts with per-cloud extensions (GCP, AWS)
|
|
20
20
|
- **Dynamic identity** - Orchestrator identity injected by UserPromptSubmit hook; skills loaded on-demand
|
|
21
|
-
- **
|
|
21
|
+
- **Dual-barrier security** - Settings deny rules (Claude Code native) + hook-level blocking (inalterable via symlink)
|
|
22
|
+
- **Indirect execution detection** - Catches `bash -c`, `eval`, `python -c` wrappers that bypass regex patterns
|
|
23
|
+
- **Approval gates** for T3 operations via native `ask` dialog
|
|
22
24
|
- **Git commit validation** with Conventional Commits
|
|
23
|
-
- **
|
|
25
|
+
- **21 skills** - Injected procedural knowledge modules for agents
|
|
24
26
|
- **Plugin + npm** - Distributable as Claude Code native plugin or npm package
|
|
27
|
+
- **Enterprise ready** - Managed settings template for organization-wide deployment
|
|
25
28
|
|
|
26
29
|
## Installation
|
|
27
30
|
|
|
@@ -56,12 +59,24 @@ gaia-scan
|
|
|
56
59
|
|
|
57
60
|
This will:
|
|
58
61
|
1. Auto-detect your project structure (GitOps, Terraform, AppServices)
|
|
59
|
-
2.
|
|
60
|
-
3.
|
|
61
|
-
4.
|
|
62
|
+
2. Create `.claude/` directory with symlinks to this package
|
|
63
|
+
3. Generate `project-context.json`
|
|
64
|
+
4. Create `settings.json` with hooks only (no permissions in settings.json)
|
|
65
|
+
5. Merge deny rules + allow permissions into `settings.local.json` (preserves existing user config)
|
|
62
66
|
|
|
63
67
|
No `CLAUDE.md` is generated -- orchestrator identity is injected dynamically by the UserPromptSubmit hook.
|
|
64
68
|
|
|
69
|
+
### Settings Architecture
|
|
70
|
+
|
|
71
|
+
Gaia-Ops separates hooks from permissions:
|
|
72
|
+
|
|
73
|
+
| File | Content | Strategy |
|
|
74
|
+
|------|---------|----------|
|
|
75
|
+
| `settings.json` | Hooks only (9 hook types) | Overwritten from template on each update |
|
|
76
|
+
| `settings.local.json` | Permissions (allow + deny rules) | Union merge — never removes user config |
|
|
77
|
+
|
|
78
|
+
This ensures your personal customizations (MCP servers, extra permissions) survive updates.
|
|
79
|
+
|
|
65
80
|
### Manual Installation
|
|
66
81
|
|
|
67
82
|
```bash
|
|
@@ -100,17 +115,34 @@ npx gaia-skills-diagnose
|
|
|
100
115
|
npx gaia-skills-diagnose --run-tests
|
|
101
116
|
```
|
|
102
117
|
|
|
118
|
+
## Security
|
|
119
|
+
|
|
120
|
+
Gaia-Ops enforces a 6-layer security pipeline:
|
|
121
|
+
|
|
122
|
+
| Layer | Mechanism | Bypassable? |
|
|
123
|
+
|-------|-----------|-------------|
|
|
124
|
+
| Indirect execution detection | `bash -c`, `eval`, `python -c` wrappers | No (hook-level) |
|
|
125
|
+
| Blocked commands (regex) | 85+ regex patterns | No (symlink to npm package) |
|
|
126
|
+
| Blocked commands (semantic) | 70+ ordered-token rules | No (symlink to npm package) |
|
|
127
|
+
| Cloud pipe validator | Credential piping detection | No (hook-level) |
|
|
128
|
+
| Mutative verb detection | `ask` dialog for state-changing ops | User approves via native dialog |
|
|
129
|
+
| Settings deny rules | 147 deny rules in `settings.local.json` | Self-healing (restored each session) |
|
|
130
|
+
|
|
131
|
+
### Enterprise Deployment
|
|
132
|
+
|
|
133
|
+
For organization-wide enforcement, deploy `templates/managed-settings.template.json` as a managed settings policy via Claude.ai Admin Console. Managed settings have the highest precedence and cannot be overridden.
|
|
134
|
+
|
|
103
135
|
## Project Structure
|
|
104
136
|
|
|
105
137
|
```
|
|
106
138
|
node_modules/@jaguilar87/gaia-ops/
|
|
107
139
|
├── agents/ # Agent definitions (6 agents)
|
|
108
|
-
├── skills/ # Skill modules (
|
|
140
|
+
├── skills/ # Skill modules (21 skills)
|
|
109
141
|
├── tools/ # Orchestration tools
|
|
110
142
|
├── hooks/ # Claude Code hooks (modular architecture)
|
|
111
143
|
├── commands/ # Slash commands (5 speckit + scan-project)
|
|
112
144
|
├── config/ # Configuration (contracts, git standards, rules)
|
|
113
|
-
├── templates/ # Installation templates (settings, governance)
|
|
145
|
+
├── templates/ # Installation templates (settings, governance, managed-settings)
|
|
114
146
|
├── speckit/ # Spec-Kit framework (templates)
|
|
115
147
|
├── bin/ # CLI utilities (11 scripts)
|
|
116
148
|
└── tests/ # Test suite
|
|
@@ -133,7 +165,7 @@ This package follows [Semantic Versioning](https://semver.org/):
|
|
|
133
165
|
- **MINOR:** New features
|
|
134
166
|
- **PATCH:** Bug fixes
|
|
135
167
|
|
|
136
|
-
Current version: **4.
|
|
168
|
+
Current version: **4.5.0**
|
|
137
169
|
|
|
138
170
|
See [CHANGELOG.md](./CHANGELOG.md) for version history.
|
|
139
171
|
|
|
@@ -169,7 +201,7 @@ git clone git@bitbucket.org:yourorg/your-project-context.git project-context
|
|
|
169
201
|
|
|
170
202
|
- **Issues:** [GitHub Issues](https://github.com/metraton/gaia-ops/issues)
|
|
171
203
|
- **Repository:** [github.com/metraton/gaia-ops](https://github.com/metraton/gaia-ops)
|
|
172
|
-
- **Author:** Jorge Aguilar <
|
|
204
|
+
- **Author:** Jorge Aguilar <jorge.aguilar88@gmail.com>
|
|
173
205
|
|
|
174
206
|
## License
|
|
175
207
|
|
|
@@ -19,7 +19,7 @@ skills:
|
|
|
19
19
|
|
|
20
20
|
1. **Triage first**: When checking infrastructure state, run the fast-queries Terraform or cloud triage script before running plan/apply.
|
|
21
21
|
2. **Deep analysis**: When investigating drift or complex module dependencies, follow the investigation phases.
|
|
22
|
-
3. **Before T3 operations**: When `terragrunt apply` is needed, present a REVIEW plan first. If a hook blocks it,
|
|
22
|
+
3. **Before T3 operations**: When `terragrunt apply` is needed, present a REVIEW plan first. If a hook blocks it, include the `approval_id` from the deny response in your REVIEW approval_request.
|
|
23
23
|
4. **Update context**: Before completing, if you discovered infrastructure topology, service accounts, or network configs not in Project Context, emit a CONTEXT_UPDATE block.
|
|
24
24
|
|
|
25
25
|
## Identity
|
package/bin/README.md
CHANGED
|
@@ -27,7 +27,7 @@ Configure symlinks Remove files
|
|
|
27
27
|
| Script | Description |
|
|
28
28
|
|--------|-------------|
|
|
29
29
|
| `gaia-scan` | Project scanner and installer (Python) |
|
|
30
|
-
| `gaia-update.js` | Configuration updater (postinstall hook) |
|
|
30
|
+
| `gaia-update.js` | Configuration updater (postinstall hook) — updates hooks template, merges permissions into settings.local.json, ensures plugin-registry |
|
|
31
31
|
|
|
32
32
|
### Diagnostics and Monitoring
|
|
33
33
|
|
|
@@ -146,4 +146,4 @@ npx gaia-scan --non-interactive
|
|
|
146
146
|
|
|
147
147
|
---
|
|
148
148
|
|
|
149
|
-
**Version:** 4.
|
|
149
|
+
**Version:** 4.5.0 | **Updated:** 2026-03-24 | **Scripts:** 11
|
package/bin/gaia-doctor.js
CHANGED
|
@@ -102,17 +102,30 @@ async function checkSettingsJson() {
|
|
|
102
102
|
if (!hookTypes.includes('PostToolUse')) issues.push('Missing PostToolUse hook');
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
// Check permissions
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
// Check permissions — now live in settings.local.json (not settings.json)
|
|
106
|
+
const localPath = join(CWD, '.claude', 'settings.local.json');
|
|
107
|
+
let permCount = 0;
|
|
108
|
+
if (existsSync(localPath)) {
|
|
109
|
+
try {
|
|
110
|
+
const localData = JSON.parse(await fs.readFile(localPath, 'utf-8'));
|
|
111
|
+
if (localData.permissions) {
|
|
112
|
+
permCount = Object.values(localData.permissions).flat().length;
|
|
113
|
+
}
|
|
114
|
+
} catch { /* ignore parse errors */ }
|
|
115
|
+
}
|
|
116
|
+
// Also count permissions in settings.json (legacy installs)
|
|
117
|
+
if (data.permissions) {
|
|
118
|
+
permCount += Object.values(data.permissions).flat().length;
|
|
119
|
+
}
|
|
120
|
+
if (permCount === 0) {
|
|
121
|
+
issues.push('No permissions configured (check settings.local.json)');
|
|
108
122
|
}
|
|
109
123
|
|
|
110
124
|
if (issues.length > 0) {
|
|
111
|
-
return { name: 'settings.json', ok: false, detail: issues.join('; '), fix: 'Run gaia-scan' };
|
|
125
|
+
return { name: 'settings.json', ok: false, detail: issues.join('; '), fix: 'Run gaia-scan or npx gaia-update' };
|
|
112
126
|
}
|
|
113
127
|
|
|
114
128
|
const hookCount = data.hooks ? Object.keys(data.hooks).length : 0;
|
|
115
|
-
const permCount = data.permissions ? Object.values(data.permissions).flat().length : 0;
|
|
116
129
|
return { name: 'settings.json', ok: true, detail: `${hookCount} hook types, ${permCount} rules` };
|
|
117
130
|
} catch {
|
|
118
131
|
return { name: 'settings.json', ok: false, detail: 'Invalid JSON', fix: 'Delete and run gaia-scan' };
|
package/bin/gaia-history.js
CHANGED
|
@@ -125,7 +125,6 @@ function colorStatus(status) {
|
|
|
125
125
|
if (s === 'NEEDS_INPUT') return chalk.yellow(s.padEnd(8));
|
|
126
126
|
if (s === 'IN_PROGRESS') return chalk.cyan(s.padEnd(8));
|
|
127
127
|
if (s === 'REVIEW') return chalk.magenta(s.padEnd(8));
|
|
128
|
-
if (s === 'AWAITING_APPROVAL') return chalk.yellow(s.padEnd(8));
|
|
129
128
|
return chalk.gray(s.padEnd(8));
|
|
130
129
|
}
|
|
131
130
|
|
package/bin/gaia-metrics.js
CHANGED
|
@@ -450,7 +450,7 @@ function calculateAgentInvocations(workflowMetrics) {
|
|
|
450
450
|
|
|
451
451
|
/**
|
|
452
452
|
* Agent outcome distribution from plan_status field.
|
|
453
|
-
* Counts COMPLETE, BLOCKED, NEEDS_INPUT, IN_PROGRESS, REVIEW,
|
|
453
|
+
* Counts COMPLETE, BLOCKED, NEEDS_INPUT, IN_PROGRESS, REVIEW, and others.
|
|
454
454
|
* Returns null if no entries have the plan_status field (older data).
|
|
455
455
|
*/
|
|
456
456
|
function calculateAgentOutcomes(workflowMetrics) {
|
|
@@ -874,7 +874,7 @@ function displayMetrics(
|
|
|
874
874
|
// ── Agent Outcomes ───────────────────────────────────
|
|
875
875
|
if (agentOutcomes) {
|
|
876
876
|
console.log(chalk.bold(`\n📋 Agent Outcomes (${agentOutcomes.total} sessions with status)`));
|
|
877
|
-
const outcomeColor = { COMPLETE: chalk.green, BLOCKED: chalk.red, NEEDS_INPUT: chalk.yellow, IN_PROGRESS: chalk.cyan, REVIEW: chalk.magenta
|
|
877
|
+
const outcomeColor = { COMPLETE: chalk.green, BLOCKED: chalk.red, NEEDS_INPUT: chalk.yellow, IN_PROGRESS: chalk.cyan, REVIEW: chalk.magenta };
|
|
878
878
|
for (const { status, count, percentage } of agentOutcomes.distribution) {
|
|
879
879
|
const bar = makeBar(percentage, 10);
|
|
880
880
|
const pct = percentage.toFixed(1).padStart(5);
|
package/bin/gaia-scan.py
CHANGED
|
@@ -205,6 +205,7 @@ def _mode_fresh(project_root: Path, scan_config: ScanConfig, args) -> int:
|
|
|
205
205
|
generate_governance,
|
|
206
206
|
generate_project_context,
|
|
207
207
|
install_git_hooks,
|
|
208
|
+
merge_hooks_to_settings_local,
|
|
208
209
|
)
|
|
209
210
|
from tools.scan.ui import (
|
|
210
211
|
RailUI,
|
|
@@ -238,11 +239,15 @@ def _mode_fresh(project_root: Path, scan_config: ScanConfig, args) -> int:
|
|
|
238
239
|
|
|
239
240
|
# Step 4: INSTALL (automatic, no prompts)
|
|
240
241
|
skip_claude = getattr(args, "skip_claude_install", False)
|
|
242
|
+
npm_postinstall = getattr(args, "npm_postinstall", False)
|
|
241
243
|
ensure_claude_code(skip_install=skip_claude)
|
|
242
|
-
|
|
244
|
+
if not npm_postinstall:
|
|
245
|
+
# Skip when called from npm postinstall to avoid re-entrance
|
|
246
|
+
ensure_gaia_ops_package(project_root)
|
|
243
247
|
create_claude_directory(project_root)
|
|
244
248
|
copy_claude_md(project_root)
|
|
245
249
|
copy_settings_json(project_root)
|
|
250
|
+
merge_hooks_to_settings_local(project_root)
|
|
246
251
|
install_git_hooks(project_root)
|
|
247
252
|
generate_project_context(project_root, config, scan_context=output.context)
|
|
248
253
|
generate_governance(project_root, config)
|
|
@@ -284,6 +289,7 @@ def _mode_existing(project_root: Path, scan_config: ScanConfig, args) -> int:
|
|
|
284
289
|
copy_settings_json,
|
|
285
290
|
create_claude_directory,
|
|
286
291
|
install_git_hooks,
|
|
292
|
+
merge_hooks_to_settings_local,
|
|
287
293
|
)
|
|
288
294
|
from tools.scan.ui import (
|
|
289
295
|
RailUI,
|
|
@@ -314,6 +320,7 @@ def _mode_existing(project_root: Path, scan_config: ScanConfig, args) -> int:
|
|
|
314
320
|
# Step 4: SYNC
|
|
315
321
|
copy_claude_md(project_root)
|
|
316
322
|
copy_settings_json(project_root)
|
|
323
|
+
merge_hooks_to_settings_local(project_root)
|
|
317
324
|
create_claude_directory(project_root)
|
|
318
325
|
install_git_hooks(project_root)
|
|
319
326
|
|
|
@@ -496,6 +503,13 @@ def main(argv: list = None) -> int:
|
|
|
496
503
|
dest="skip_claude_install",
|
|
497
504
|
help="Skip Claude Code CLI installation",
|
|
498
505
|
)
|
|
506
|
+
parser.add_argument(
|
|
507
|
+
"--npm-postinstall",
|
|
508
|
+
action="store_true",
|
|
509
|
+
default=False,
|
|
510
|
+
dest="npm_postinstall",
|
|
511
|
+
help="Called from npm postinstall: skip Claude Code install and npm package install to avoid re-entrance",
|
|
512
|
+
)
|
|
499
513
|
|
|
500
514
|
args = parser.parse_args(argv)
|
|
501
515
|
|
|
@@ -544,11 +558,19 @@ def main(argv: list = None) -> int:
|
|
|
544
558
|
print(json.dumps(result), file=sys.stdout)
|
|
545
559
|
return 0
|
|
546
560
|
|
|
561
|
+
# --npm-postinstall implies --skip-claude-install and skips ensure_gaia_ops_package
|
|
562
|
+
if args.npm_postinstall:
|
|
563
|
+
args.skip_claude_install = True
|
|
564
|
+
|
|
547
565
|
# Mode selection
|
|
548
566
|
# --json or --scan-only: scan-only mode
|
|
549
567
|
if args.json or args.scan_only:
|
|
550
568
|
return _mode_scan_only(project_root, scan_config, args)
|
|
551
569
|
|
|
570
|
+
# --npm-postinstall: fresh install mode with re-entrance protection
|
|
571
|
+
if args.npm_postinstall:
|
|
572
|
+
return _mode_fresh(project_root, scan_config, args)
|
|
573
|
+
|
|
552
574
|
# Detect mode based on .claude/ existence
|
|
553
575
|
claude_dir = project_root / ".claude"
|
|
554
576
|
if claude_dir.is_dir():
|