@garethdaine/agentops 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/.claude-plugin/plugin.json +10 -0
  2. package/LICENSE +21 -0
  3. package/README.md +410 -0
  4. package/agents/architecture-researcher.md +115 -0
  5. package/agents/code-critic.md +190 -0
  6. package/agents/delegation-router.md +40 -0
  7. package/agents/feature-researcher.md +117 -0
  8. package/agents/interrogator.md +11 -0
  9. package/agents/pitfalls-researcher.md +112 -0
  10. package/agents/plan-validator.md +173 -0
  11. package/agents/proposer.md +61 -0
  12. package/agents/security-reviewer.md +189 -0
  13. package/agents/skill-builder.md +43 -0
  14. package/agents/spec-compliance-reviewer.md +154 -0
  15. package/agents/stack-researcher.md +89 -0
  16. package/commands/build.md +766 -0
  17. package/commands/code-analysis.md +39 -0
  18. package/commands/code-field.md +22 -0
  19. package/commands/compliance-check.md +34 -0
  20. package/commands/configure.md +178 -0
  21. package/commands/cost-report.md +17 -0
  22. package/commands/enterprise/adr.md +78 -0
  23. package/commands/enterprise/brainstorm.md +461 -0
  24. package/commands/enterprise/design.md +203 -0
  25. package/commands/enterprise/dev-setup.md +136 -0
  26. package/commands/enterprise/docker-dev.md +229 -0
  27. package/commands/enterprise/e2e.md +233 -0
  28. package/commands/enterprise/feature.md +218 -0
  29. package/commands/enterprise/gap-analysis.md +204 -0
  30. package/commands/enterprise/handover.md +195 -0
  31. package/commands/enterprise/herd.md +152 -0
  32. package/commands/enterprise/knowledge.md +173 -0
  33. package/commands/enterprise/onboard.md +86 -0
  34. package/commands/enterprise/qa-check.md +80 -0
  35. package/commands/enterprise/reason.md +196 -0
  36. package/commands/enterprise/review.md +177 -0
  37. package/commands/enterprise/scaffold.md +153 -0
  38. package/commands/enterprise/status-report.md +101 -0
  39. package/commands/enterprise/tech-catalog.md +170 -0
  40. package/commands/enterprise/test-gen.md +138 -0
  41. package/commands/evolve.md +39 -0
  42. package/commands/flags.md +44 -0
  43. package/commands/interrogate.md +263 -0
  44. package/commands/lesson.md +15 -0
  45. package/commands/lessons.md +10 -0
  46. package/commands/plan.md +44 -0
  47. package/commands/prune.md +27 -0
  48. package/commands/star.md +17 -0
  49. package/commands/supply-chain-scan.md +44 -0
  50. package/commands/unicode-scan.md +63 -0
  51. package/commands/verify.md +41 -0
  52. package/commands/workflow.md +436 -0
  53. package/hooks/ai-guardrails.sh +114 -0
  54. package/hooks/audit-log.sh +26 -0
  55. package/hooks/auto-delegate.sh +45 -0
  56. package/hooks/auto-evolve.sh +22 -0
  57. package/hooks/auto-lesson.sh +26 -0
  58. package/hooks/auto-plan.sh +59 -0
  59. package/hooks/auto-test.sh +46 -0
  60. package/hooks/auto-verify.sh +30 -0
  61. package/hooks/budget-check.sh +24 -0
  62. package/hooks/code-field-preamble.sh +30 -0
  63. package/hooks/compliance-gate.sh +50 -0
  64. package/hooks/content-trust.sh +22 -0
  65. package/hooks/credential-redact.sh +23 -0
  66. package/hooks/delegation-trust.sh +15 -0
  67. package/hooks/detect-test-run.sh +19 -0
  68. package/hooks/enforcement-lib.sh +60 -0
  69. package/hooks/evolve-gate.sh +32 -0
  70. package/hooks/evolve-lib.sh +32 -0
  71. package/hooks/exfiltration-check.sh +67 -0
  72. package/hooks/failure-collector.sh +27 -0
  73. package/hooks/feature-flags.sh +67 -0
  74. package/hooks/file-provenance.sh +31 -0
  75. package/hooks/flag-utils.sh +36 -0
  76. package/hooks/hooks.json +145 -0
  77. package/hooks/injection-scan.sh +58 -0
  78. package/hooks/integrity-verify.sh +91 -0
  79. package/hooks/lessons-check.sh +17 -0
  80. package/hooks/lockfile-audit.sh +109 -0
  81. package/hooks/patterns-lib.sh +22 -0
  82. package/hooks/plan-gate.sh +18 -0
  83. package/hooks/redact-lib.sh +15 -0
  84. package/hooks/runtime-mode.sh +56 -0
  85. package/hooks/session-cleanup.sh +74 -0
  86. package/hooks/skill-validator.sh +28 -0
  87. package/hooks/standards-enforce.sh +106 -0
  88. package/hooks/star-gate.sh +93 -0
  89. package/hooks/star-preamble.sh +10 -0
  90. package/hooks/telemetry.sh +33 -0
  91. package/hooks/todo-prune.sh +84 -0
  92. package/hooks/unicode-firewall.sh +122 -0
  93. package/hooks/unicode-lib.sh +66 -0
  94. package/hooks/unicode-scan-session.sh +96 -0
  95. package/hooks/validate-command.sh +103 -0
  96. package/hooks/validate-env.sh +51 -0
  97. package/hooks/validate-path.sh +81 -0
  98. package/package.json +40 -0
  99. package/settings.json +6 -0
  100. package/templates/ai-config/tool-standards.md +56 -0
  101. package/templates/architecture/api-first.md +192 -0
  102. package/templates/architecture/auth-patterns.md +302 -0
  103. package/templates/architecture/caching-strategy.md +359 -0
  104. package/templates/architecture/database-patterns.md +347 -0
  105. package/templates/architecture/event-driven.md +252 -0
  106. package/templates/architecture/integration-patterns.md +185 -0
  107. package/templates/architecture/multi-tenancy.md +104 -0
  108. package/templates/architecture/service-boundaries.md +200 -0
  109. package/templates/build/brief-template.md +86 -0
  110. package/templates/build/summary-template.md +100 -0
  111. package/templates/build/task-plan-template.md +133 -0
  112. package/templates/communication/effort-estimate.md +54 -0
  113. package/templates/communication/incident-response.md +59 -0
  114. package/templates/communication/post-mortem.md +109 -0
  115. package/templates/communication/risk-register.md +43 -0
  116. package/templates/communication/sprint-demo-checklist.md +64 -0
  117. package/templates/communication/stakeholder-presentation-outline.md +84 -0
  118. package/templates/communication/technical-proposal.md +77 -0
  119. package/templates/delivery/deployment/deployment-checklist.md +49 -0
  120. package/templates/delivery/design/solution-design-checklist.md +37 -0
  121. package/templates/delivery/discovery/stakeholder-questions.md +33 -0
  122. package/templates/delivery/handover/knowledge-transfer-checklist.md +75 -0
  123. package/templates/delivery/handover/operational-runbook.md +117 -0
  124. package/templates/delivery/handover/support-escalation-matrix.md +56 -0
  125. package/templates/delivery/implementation/blocker-escalation-template.md +55 -0
  126. package/templates/delivery/implementation/sprint-planning-template.md +49 -0
  127. package/templates/delivery/implementation/task-decomposition-guide.md +59 -0
  128. package/templates/delivery/qa/test-plan-template.md +76 -0
  129. package/templates/delivery/qa/test-results-template.md +55 -0
  130. package/templates/delivery/qa/uat-signoff-template.md +44 -0
  131. package/templates/governance/codeowners.md +60 -0
  132. package/templates/integration/adapter-pattern.md +160 -0
  133. package/templates/scaffolds/env-validation.md +85 -0
  134. package/templates/scaffolds/error-handling.md +171 -0
  135. package/templates/scaffolds/graceful-shutdown.md +139 -0
  136. package/templates/scaffolds/health-check.md +109 -0
  137. package/templates/scaffolds/structured-logging.md +134 -0
  138. package/templates/standards/engineering-standards.md +413 -0
  139. package/templates/standards/standards-checklist.md +125 -0
  140. package/templates/tech-catalog.json +663 -0
  141. package/templates/utilities/project-detection.md +75 -0
  142. package/templates/utilities/requirements-collection.md +68 -0
  143. package/templates/utilities/template-rendering.md +81 -0
  144. package/templates/workflows/architecture-decision.md +90 -0
  145. package/templates/workflows/bug-investigation.md +83 -0
  146. package/templates/workflows/feature-implementation.md +80 -0
  147. package/templates/workflows/refactoring.md +83 -0
  148. package/templates/workflows/spike-exploration.md +82 -0
@@ -0,0 +1,66 @@
1
+ #!/bin/bash
2
+ # Shared Unicode detection library — single source of truth for Glassworm/Trojan Source defense.
3
+ # Sourced by: unicode-firewall.sh, unicode-scan-session.sh, lockfile-audit.sh
4
+
5
+ # Dangerous invisible Unicode character ranges:
6
+ # Cat 1: Zero-width / invisible U+200B-200F, U+2060-2064, U+FEFF
7
+ # Cat 2: Bidi overrides U+202A-202E, U+2066-2069
8
+ # Cat 3: Variation selectors U+FE00-FE0F
9
+ # Cat 4: Tag characters U+E0001-E007F
10
+ # Cat 5: Variation sel. supp. U+E0100-E01EF
11
+ UNICODE_PATTERN='[\x{200B}-\x{200F}\x{2060}-\x{2064}\x{FEFF}\x{202A}-\x{202E}\x{2066}-\x{2069}\x{FE00}-\x{FE0F}\x{E0001}-\x{E007F}\x{E0100}-\x{E01EF}]'
12
+
13
+ # Returns 0 (match) if dangerous invisible Unicode is found in stdin.
14
+ unicode_detect() {
15
+ perl -CSD -ne "if (/$UNICODE_PATTERN/) { exit 0 } END { exit 1 }" 2>/dev/null
16
+ }
17
+
18
+ # Returns 0 (match) if dangerous invisible Unicode is found in a file.
19
+ unicode_detect_file() {
20
+ local FILE="$1"
21
+ perl -CSD -ne "if (/$UNICODE_PATTERN/) { exit 0 } END { exit 1 }" "$FILE" 2>/dev/null
22
+ }
23
+
24
+ # Returns human-readable category summary from stdin.
25
+ unicode_classify() {
26
+ perl -CSD -ne '
27
+ BEGIN { %c = () }
28
+ $c{"zero-width chars"}++ if /[\x{200B}-\x{200F}\x{2060}-\x{2064}\x{FEFF}]/;
29
+ $c{"bidi overrides"}++ if /[\x{202A}-\x{202E}\x{2066}-\x{2069}]/;
30
+ $c{"variation selectors"}++ if /[\x{FE00}-\x{FE0F}]/;
31
+ $c{"tag characters"}++ if /[\x{E0001}-\x{E007F}]/;
32
+ $c{"variation sel. supplement"}++ if /[\x{E0100}-\x{E01EF}]/;
33
+ END { print join(", ", sort keys %c) if %c }
34
+ ' 2>/dev/null
35
+ }
36
+
37
+ # Returns human-readable category summary from a file.
38
+ unicode_classify_file() {
39
+ local FILE="$1"
40
+ perl -CSD -ne '
41
+ BEGIN { %c = () }
42
+ $c{"zero-width chars"}++ if /[\x{200B}-\x{200F}\x{2060}-\x{2064}\x{FEFF}]/;
43
+ $c{"bidi overrides"}++ if /[\x{202A}-\x{202E}\x{2066}-\x{2069}]/;
44
+ $c{"variation selectors"}++ if /[\x{FE00}-\x{FE0F}]/;
45
+ $c{"tag characters"}++ if /[\x{E0001}-\x{E007F}]/;
46
+ $c{"variation sel. supplement"}++ if /[\x{E0100}-\x{E01EF}]/;
47
+ END { print join(", ", sort keys %c) if %c }
48
+ ' "$FILE" 2>/dev/null
49
+ }
50
+
51
+ # Count affected lines from stdin.
52
+ unicode_count_lines() {
53
+ perl -CSD -ne "print if /$UNICODE_PATTERN/" 2>/dev/null | wc -l | tr -d ' '
54
+ }
55
+
56
+ # Count affected lines in a file.
57
+ unicode_count_lines_file() {
58
+ local FILE="$1"
59
+ perl -CSD -ne "print if /$UNICODE_PATTERN/" "$FILE" 2>/dev/null | wc -l | tr -d ' '
60
+ }
61
+
62
+ # Strip dangerous Unicode from a file in-place.
63
+ unicode_strip_file() {
64
+ local FILE="$1"
65
+ perl -CSD -pi -e "s/$UNICODE_PATTERN//g" "$FILE" 2>/dev/null
66
+ }
@@ -0,0 +1,96 @@
1
+ #!/bin/bash
2
+ set -uo pipefail
3
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
4
+ source "${SCRIPT_DIR}/feature-flags.sh"
5
+
6
+ [ "$(agentops_flag 'unicode_firewall_enabled')" = "false" ] && exit 0
7
+
8
+ source "${SCRIPT_DIR}/unicode-lib.sh"
9
+
10
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
11
+ CACHE_DIR="${PROJECT_DIR}/.agentops"
12
+ CACHE_FILE="${CACHE_DIR}/unicode-scan-cache"
13
+
14
+ # Skip scan if cache exists and no files have been modified since last scan
15
+ if [ -f "$CACHE_FILE" ]; then
16
+ NEWER_FILES=$(find "$PROJECT_DIR" \
17
+ -type f \
18
+ \( -name '*.js' -o -name '*.ts' -o -name '*.tsx' -o -name '*.jsx' \
19
+ -o -name '*.py' -o -name '*.rb' -o -name '*.go' -o -name '*.rs' \
20
+ -o -name '*.java' -o -name '*.php' -o -name '*.sh' -o -name '*.json' \
21
+ -o -name '*.yaml' -o -name '*.yml' -o -name '*.md' -o -name '*.env' \) \
22
+ -not -path '*/.git/*' \
23
+ -not -path '*/node_modules/*' \
24
+ -not -path '*/vendor/*' \
25
+ -not -path '*/.agentops/*' \
26
+ -newer "$CACHE_FILE" \
27
+ -print -quit 2>/dev/null)
28
+ if [ -z "$NEWER_FILES" ]; then
29
+ # No files modified since last scan — use cached result
30
+ CACHED_MSG=$(cat "$CACHE_FILE" 2>/dev/null)
31
+ [ -n "$CACHED_MSG" ] && echo "$CACHED_MSG"
32
+ exit 0
33
+ fi
34
+ fi
35
+
36
+ # Scan project directory for files containing dangerous invisible Unicode.
37
+ # Skips: .git, node_modules, vendor, .agentops, binary files, lock files.
38
+ RESULTS=$(find "$PROJECT_DIR" \
39
+ -type f \
40
+ \( -name '*.js' -o -name '*.ts' -o -name '*.tsx' -o -name '*.jsx' \
41
+ -o -name '*.py' -o -name '*.rb' -o -name '*.go' -o -name '*.rs' \
42
+ -o -name '*.java' -o -name '*.php' -o -name '*.c' -o -name '*.cpp' \
43
+ -o -name '*.h' -o -name '*.hpp' -o -name '*.cs' -o -name '*.swift' \
44
+ -o -name '*.kt' -o -name '*.scala' -o -name '*.sh' -o -name '*.bash' \
45
+ -o -name '*.vue' -o -name '*.svelte' -o -name '*.json' -o -name '*.yaml' \
46
+ -o -name '*.yml' -o -name '*.toml' -o -name '*.xml' -o -name '*.md' \
47
+ -o -name '*.txt' -o -name '*.html' -o -name '*.css' -o -name '*.scss' \
48
+ -o -name '*.env' -o -name '*.env.*' -o -name 'Makefile' -o -name 'Dockerfile' \
49
+ -o -name '*.cfg' -o -name '*.ini' -o -name '*.conf' \) \
50
+ -not -path '*/.git/*' \
51
+ -not -path '*/node_modules/*' \
52
+ -not -path '*/vendor/*' \
53
+ -not -path '*/.agentops/*' \
54
+ -not -path '*/dist/*' \
55
+ -not -path '*/build/*' \
56
+ -not -path '*/*.min.js' \
57
+ -not -path '*/*.min.css' \
58
+ -not -name 'package-lock.json' \
59
+ -not -name 'yarn.lock' \
60
+ -not -name 'pnpm-lock.yaml' \
61
+ -not -name 'composer.lock' \
62
+ -not -name 'Cargo.lock' \
63
+ -not -name 'Gemfile.lock' \
64
+ -print0 2>/dev/null | \
65
+ xargs -0 perl -CSD -lne "
66
+ if (/$UNICODE_PATTERN/) {
67
+ print \$ARGV;
68
+ close ARGV; # skip to next file after first match
69
+ }
70
+ " 2>/dev/null | sort -u)
71
+
72
+ if [ -n "$RESULTS" ]; then
73
+ FILE_COUNT=$(echo "$RESULTS" | wc -l | tr -d ' ')
74
+
75
+ # Build a truncated file list (max 10 files shown)
76
+ FILE_LIST=$(echo "$RESULTS" | head -10 | sed "s|^$PROJECT_DIR/||")
77
+ [ "$FILE_COUNT" -gt 10 ] && FILE_LIST="${FILE_LIST}
78
+ ... and $((FILE_COUNT - 10)) more"
79
+
80
+ # Audit log
81
+ LOG_DIR="${PROJECT_DIR}/.agentops"
82
+ mkdir -p "$LOG_DIR" 2>/dev/null
83
+ jq -nc --arg ts "$(date -u +%FT%TZ)" --arg count "$FILE_COUNT" \
84
+ '{ts:$ts, event:"UNICODE_SESSION_SCAN", files_flagged:($count|tonumber)}' >> "$LOG_DIR/audit.jsonl" 2>/dev/null
85
+
86
+ OUTPUT=$(jq -nc --arg count "$FILE_COUNT" --arg files "$FILE_LIST" \
87
+ '{systemMessage:("UNICODE FIREWALL — SESSION SCAN: Found " + $count + " file(s) containing dangerous invisible Unicode characters (zero-width, bidi overrides, variation selectors, or tag characters). These may indicate a Glassworm/Trojan Source supply-chain compromise.\n\nAffected files:\n" + $files + "\n\nRun /agentops:unicode-scan to get a detailed analysis and clean these files.")}')
88
+ echo "$OUTPUT"
89
+ mkdir -p "$CACHE_DIR" 2>/dev/null
90
+ echo "$OUTPUT" > "$CACHE_FILE" 2>/dev/null
91
+ else
92
+ OUTPUT=$(jq -nc '{systemMessage:"Unicode firewall: session scan clean — no dangerous invisible characters detected in project files."}')
93
+ echo "$OUTPUT"
94
+ mkdir -p "$CACHE_DIR" 2>/dev/null
95
+ echo "$OUTPUT" > "$CACHE_FILE" 2>/dev/null
96
+ fi
@@ -0,0 +1,103 @@
1
+ #!/bin/bash
2
+ set -uo pipefail
3
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
4
+ source "${SCRIPT_DIR}/feature-flags.sh"
5
+
6
+ [ "$(agentops_flag 'command_validation_enabled')" = "false" ] && exit 0
7
+
8
+ INPUT=$(cat) || exit 0
9
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null) || agentops_fail_closed
10
+ [ -z "$COMMAND" ] && exit 0
11
+
12
+ # Hard-deny rules execute BEFORE bypass check — they always enforce.
13
+ HARD_DENY=$(agentops_hard_deny)
14
+
15
+ # 1. Destructive system commands (always deny, even in bypass/unrestricted)
16
+ if echo "$COMMAND" | grep -qE "(rm\s+-rf\s+/[^t]|mkfs\s|dd\s+if=|shutdown|reboot|init\s+[06])"; then
17
+ jq -nc --arg action "$HARD_DENY" \
18
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:"Destructive system command blocked by AgentOps CommandPolicy (hard deny)"}}'
19
+ exit 0
20
+ fi
21
+
22
+ # 2. Indirect execution of destructive commands (always deny)
23
+ if echo "$COMMAND" | grep -qE "(eval\s|bash\s+-c|sh\s+-c|exec\s)" && echo "$COMMAND" | grep -qiE "(rm\s+-rf|chmod\s+777|curl.*\|.*sh|wget.*\|.*bash|mkfs|dd\s+if=)"; then
24
+ jq -nc --arg action "$HARD_DENY" \
25
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:"Indirect execution of dangerous command blocked by AgentOps CommandPolicy (hard deny)"}}'
26
+ exit 0
27
+ fi
28
+
29
+ # 3. Fork bomb / resource exhaustion (always deny)
30
+ if echo "$COMMAND" | grep -qE ':\(\)\{|:\(\)\s*\{|\(\)\s*\{.*\|.*:\s*;'; then
31
+ jq -nc --arg action "$HARD_DENY" \
32
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:"Fork bomb pattern detected (hard deny)"}}'
33
+ exit 0
34
+ fi
35
+
36
+ # 4. Tampering with .agentops/ state files via Bash (always deny)
37
+ # Covers: writes, deletions, permission changes, symlink replacement
38
+ # Exception: AGENTOPS_WRITABLE_STATE paths (e.g. flags.json) are whitelisted
39
+ if echo "$COMMAND" | grep -qE '>\s*[^ ]*\.agentops/' \
40
+ || echo "$COMMAND" | grep -qE '(tee|cp|mv|install)\s+[^ ]*\s+[^ ]*\.agentops/' \
41
+ || echo "$COMMAND" | grep -qE '(tee|cp|mv|install)\s+[^ ]*\.agentops/' \
42
+ || echo "$COMMAND" | grep -qE 'sed\s+-i[^ ]*\s+[^ ]*\.agentops/' \
43
+ || echo "$COMMAND" | grep -qE 'dd\s+of=[^ ]*\.agentops/' \
44
+ || echo "$COMMAND" | grep -qE '(rm|unlink|shred|truncate)\s+[^ ]*\.agentops/' \
45
+ || echo "$COMMAND" | grep -qE '(chmod|chown)\s+[^ ]*\s+[^ ]*\.agentops/' \
46
+ || echo "$COMMAND" | grep -qE '(ln)\s+[^ ]*\s+[^ ]*\.agentops/'; then
47
+ if ! echo "$COMMAND" | grep -qE "$AGENTOPS_WRITABLE_STATE"; then
48
+ jq -nc --arg action "$HARD_DENY" \
49
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:"Tampering with .agentops/ state files via Bash is blocked by AgentOps CommandPolicy (hard deny)"}}'
50
+ exit 0
51
+ fi
52
+ fi
53
+
54
+ # 4b. Tampering with hooks/ directory via Bash (always deny — prevent hook tampering)
55
+ if echo "$COMMAND" | grep -qE '>\s*[^ ]*hooks/' \
56
+ || echo "$COMMAND" | grep -qE '(tee|cp|mv|install)\s+[^ ]*\s+[^ ]*hooks/' \
57
+ || echo "$COMMAND" | grep -qE 'sed\s+-i[^ ]*\s+[^ ]*hooks/' \
58
+ || echo "$COMMAND" | grep -qE '(rm|unlink|shred|truncate)\s+[^ ]*hooks/' \
59
+ || echo "$COMMAND" | grep -qE '(chmod|chown)\s+[^ ]*\s+[^ ]*hooks/' \
60
+ || echo "$COMMAND" | grep -qE '(ln)\s+[^ ]*\s+[^ ]*hooks/'; then
61
+ jq -nc --arg action "$HARD_DENY" \
62
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:"Tampering with hooks/ directory via Bash is blocked by AgentOps CommandPolicy (hard deny)"}}'
63
+ exit 0
64
+ fi
65
+
66
+ # Soft rules below — bypass/unrestricted can downgrade these
67
+ agentops_is_bypass "$INPUT" && agentops_bypass_advisory "validate-command"
68
+ ACTION=$(agentops_enforcement_action)
69
+
70
+ # 5. Shell injection + dangerous pattern combo
71
+ if echo "$COMMAND" | grep -qE '\|\||&&' && echo "$COMMAND" | grep -qiE "(rm\s+-rf|chmod\s+777|curl.*\|.*sh|wget.*\|.*bash)"; then
72
+ jq -nc --arg action "$ACTION" \
73
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:"Shell injection risk: chained operators with dangerous command"}}'
74
+ exit 0
75
+ fi
76
+
77
+ # 6. Pipe-to-shell without chaining operators
78
+ if echo "$COMMAND" | grep -qE "(curl|wget)\s.*\|\s*(bash|sh|zsh|dash)\b"; then
79
+ jq -nc --arg action "$ACTION" \
80
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:"Pipe-to-shell pattern detected"}}'
81
+ exit 0
82
+ fi
83
+
84
+ # 7. Credential file access
85
+ if echo "$COMMAND" | grep -qiE "(/etc/shadow|/etc/passwd|\.ssh/id_|\.env\b|\.pem\b)" && echo "$COMMAND" | grep -qE "(cat|less|head|more|tail|grep|jq|python|ruby|node|base64|xxd)\s"; then
86
+ jq -nc --arg action "$ACTION" \
87
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:"Credential/sensitive file access detected"}}'
88
+ exit 0
89
+ fi
90
+
91
+ # 8. Bash accessing system directories (HS-1 — path validation for Bash tool)
92
+ if echo "$COMMAND" | grep -qE "^/(etc|proc|sys|dev|boot|root|sbin)(/|\s)" || echo "$COMMAND" | grep -qE "\s/(etc|proc|sys|dev|boot|root|sbin)(/|\s)"; then
93
+ jq -nc --arg action "$ACTION" \
94
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:"Bash command references system directory — review before proceeding"}}'
95
+ exit 0
96
+ fi
97
+
98
+ # 9. Bash accessing sensitive dotfiles (HS-1)
99
+ if echo "$COMMAND" | grep -qE "/\.(ssh|gnupg|aws|docker/config\.json|kube/config|npmrc|pypirc|netrc|git-credentials)"; then
100
+ jq -nc --arg action "$ACTION" \
101
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:"Bash command references sensitive dotfile/directory"}}'
102
+ exit 0
103
+ fi
@@ -0,0 +1,51 @@
1
+ #!/bin/bash
2
+ set -uo pipefail
3
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
4
+ source "${SCRIPT_DIR}/feature-flags.sh"
5
+
6
+ [ "$(agentops_flag 'env_validation_enabled')" = "false" ] && exit 0
7
+
8
+ INPUT=$(cat) || exit 0
9
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null) || agentops_fail_closed
10
+ [ -z "$COMMAND" ] && exit 0
11
+
12
+ # Only check commands that set env vars (case-insensitive to catch export path=, Ld_Preload=, etc.)
13
+ echo "$COMMAND" | grep -qiE "(export\s+|^[A-Za-z_]+=)" || exit 0
14
+
15
+ VARS=$(echo "$COMMAND" | grep -oiE '\b[A-Za-z_][A-Za-z0-9_]*=' | sed 's/=$//' 2>/dev/null) || exit 0
16
+
17
+ # --- Hard-deny rules (always enforce, even in bypass mode) ---
18
+ HARD_DENY=$(agentops_hard_deny)
19
+
20
+ for VAR in $VARS; do
21
+ # Normalize to uppercase for comparison
22
+ VAR_UPPER=$(echo "$VAR" | tr '[:lower:]' '[:upper:]')
23
+
24
+ # Forbidden keys — LD_PRELOAD, PATH, HOME etc. are always dangerous
25
+ if echo "$VAR_UPPER" | grep -qE "^(PATH|HOME|SHELL|USER|LD_PRELOAD|LD_LIBRARY_PATH|DYLD_)"; then
26
+ jq -nc --arg var "$VAR" --arg action "$HARD_DENY" \
27
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:("EnvPolicy: forbidden env var " + $var + " (hard deny)")}}'
28
+ exit 0
29
+ fi
30
+
31
+ # DB credentials — always deny
32
+ if echo "$VAR_UPPER" | grep -qE "^(DB_|TEST_DB_|REDIS_|MYSQL_|POSTGRES_)"; then
33
+ jq -nc --arg var "$VAR" --arg action "$HARD_DENY" \
34
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:("EnvPolicy: database credential var " + $var + " (hard deny)")}}'
35
+ exit 0
36
+ fi
37
+ done
38
+
39
+ # --- Soft rules (bypass can skip these) ---
40
+ agentops_is_bypass "$INPUT" && agentops_bypass_advisory "validate-env"
41
+ ACTION=$(agentops_enforcement_action)
42
+
43
+ for VAR in $VARS; do
44
+ VAR_UPPER=$(echo "$VAR" | tr '[:lower:]' '[:upper:]')
45
+ # Secret patterns
46
+ if echo "$VAR_UPPER" | grep -qE "(SECRET|TOKEN|PASSWORD|PASS|PRIVATE|CREDENTIAL|API_KEY|AUTH)"; then
47
+ jq -nc --arg var "$VAR" --arg action "$ACTION" \
48
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:("EnvPolicy: var matches secret pattern (" + $var + ")")}}'
49
+ exit 0
50
+ fi
51
+ done
@@ -0,0 +1,81 @@
1
+ #!/bin/bash
2
+ set -uo pipefail
3
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
4
+ source "${SCRIPT_DIR}/feature-flags.sh"
5
+
6
+ [ "$(agentops_flag 'path_validation_enabled')" = "false" ] && exit 0
7
+
8
+ INPUT=$(cat) || exit 0
9
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null) || agentops_fail_closed
10
+
11
+ # Extract path based on tool
12
+ case "$TOOL" in
13
+ Read|Write|Edit) FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null) ;;
14
+ Glob|Grep) FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.path // empty' 2>/dev/null) ;;
15
+ *) exit 0 ;;
16
+ esac
17
+
18
+ [ -z "$FILE_PATH" ] && exit 0
19
+
20
+ # --- Hard-deny rules (always enforce, even in bypass mode) ---
21
+
22
+ # 1. Must be absolute
23
+ if [[ "$FILE_PATH" != /* ]]; then
24
+ jq -nc --arg fp "$FILE_PATH" \
25
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:("PathPolicy: path must be absolute (got: " + $fp + ")")}}'
26
+ exit 0
27
+ fi
28
+
29
+ # 2. Path traversal
30
+ if echo "$FILE_PATH" | grep -qE '\.\.(/|$)'; then
31
+ jq -nc '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:"PathPolicy: path traversal (..) blocked"}}'
32
+ exit 0
33
+ fi
34
+
35
+ # 3. Length limit (1024 chars)
36
+ if [ ${#FILE_PATH} -gt 1024 ]; then
37
+ jq -nc '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:"PathPolicy: path exceeds 1024 character limit"}}'
38
+ exit 0
39
+ fi
40
+
41
+ # Canonicalize for symlink resolution (for Write/Edit, resolve existing paths)
42
+ CANONICAL="$FILE_PATH"
43
+ if [ "$TOOL" = "Write" ] || [ "$TOOL" = "Edit" ]; then
44
+ PARENT_DIR=$(dirname "$FILE_PATH")
45
+ if [ -d "$PARENT_DIR" ]; then
46
+ RESOLVED=$(realpath -m "$FILE_PATH" 2>/dev/null) || RESOLVED="$FILE_PATH"
47
+ CANONICAL="$RESOLVED"
48
+ fi
49
+ fi
50
+
51
+ # 4. Protect plugin state files from agent writes (hard deny)
52
+ # Exception: AGENTOPS_WRITABLE_STATE paths (e.g. flags.json) are whitelisted
53
+ if [ "$TOOL" = "Write" ] || [ "$TOOL" = "Edit" ]; then
54
+ if echo "$CANONICAL" | grep -qE "$AGENTOPS_PROTECTED_PATHS"; then
55
+ if ! echo "$CANONICAL" | grep -qE "$AGENTOPS_WRITABLE_STATE"; then
56
+ jq -nc --arg fp "$CANONICAL" \
57
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:("PathPolicy: protected AgentOps state file (" + $fp + ")")}}'
58
+ exit 0
59
+ fi
60
+ fi
61
+ fi
62
+
63
+ # --- Soft rules (bypass/unrestricted can downgrade) ---
64
+ agentops_is_bypass "$INPUT" && agentops_bypass_advisory "validate-path"
65
+ ACTION=$(agentops_enforcement_action)
66
+
67
+ # 5. System directory confinement (check both raw and canonical)
68
+ for CHECK_PATH in "$FILE_PATH" "$CANONICAL"; do
69
+ if echo "$CHECK_PATH" | grep -qE "^/(etc|proc|sys|dev|boot|root|sbin)(/|$)"; then
70
+ jq -nc --arg fp "$CHECK_PATH" --arg action "$ACTION" \
71
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:("PathPolicy: access to system directory blocked (" + $fp + ")")}}'
72
+ exit 0
73
+ fi
74
+ done
75
+
76
+ # 6. Sensitive dotfiles
77
+ if echo "$CANONICAL" | grep -qE "/\.(ssh|gnupg|aws|docker/config\.json|kube/config)"; then
78
+ jq -nc --arg fp "$CANONICAL" --arg action "$ACTION" \
79
+ '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$action,permissionDecisionReason:("PathPolicy: sensitive dotfile/directory access (" + $fp + ")")}}'
80
+ exit 0
81
+ fi
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@garethdaine/agentops",
3
+ "version": "0.9.0",
4
+ "description": "Enterprise guardrails, delivery lifecycle, and self-evolution for Claude Code CLI",
5
+ "author": {
6
+ "name": "Gareth Daine",
7
+ "email": "1745959+garethdaine@users.noreply.github.com"
8
+ },
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/garethdaine/agentops.git"
13
+ },
14
+ "homepage": "https://github.com/garethdaine/agentops",
15
+ "bugs": {
16
+ "url": "https://github.com/garethdaine/agentops/issues"
17
+ },
18
+ "keywords": [
19
+ "claude-code",
20
+ "claude-code-plugin",
21
+ "guardrails",
22
+ "security",
23
+ "tdd",
24
+ "delivery",
25
+ "enterprise",
26
+ "ai-agent",
27
+ "compliance",
28
+ "audit"
29
+ ],
30
+ "files": [
31
+ ".claude-plugin/",
32
+ "agents/",
33
+ "commands/",
34
+ "hooks/",
35
+ "templates/",
36
+ "settings.json",
37
+ "LICENSE",
38
+ "README.md"
39
+ ]
40
+ }
package/settings.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [],
4
+ "deny": []
5
+ }
6
+ }
@@ -0,0 +1,56 @@
1
+ # Shared AI Configuration: Tool Standards
2
+
3
+ ## Approved AI Tools by Task
4
+
5
+ | Task | Primary Tool | Alternative | Notes |
6
+ |------|-------------|-------------|-------|
7
+ | Architecture decisions | Claude (Opus) | — | Needs deep reasoning |
8
+ | Feature implementation | Claude Code | Cursor | Structured workflow via /agentops:feature |
9
+ | Code review | Claude Code | — | Via /agentops:review |
10
+ | Bug investigation | Claude Code | — | Via bug-investigation workflow |
11
+ | Documentation | Claude (Sonnet) | — | Fast, high-quality prose |
12
+ | Test generation | Claude Code | — | Via /agentops:test-gen |
13
+ | Refactoring | Claude Code | Cursor | Via refactoring workflow |
14
+
15
+ ## AI Output Quality Standards
16
+
17
+ ### Code Quality
18
+ - Generated code must pass TypeScript strict mode
19
+ - No `any` types unless explicitly justified
20
+ - All functions must handle error cases
21
+ - No placeholder values (TODO, FIXME, example.com)
22
+ - Follows existing project patterns and conventions
23
+
24
+ ### Documentation Quality
25
+ - Clear, concise, professional tone
26
+ - No hallucinated links or references
27
+ - All code examples must be syntactically correct
28
+ - Technical accuracy verified against codebase
29
+
30
+ ### Review Quality
31
+ - All findings must reference specific file:line locations
32
+ - Fix suggestions must be concrete and implementable
33
+ - Severity ratings must be justified
34
+ - No false positives from pattern matching
35
+
36
+ ## Model Selection Guide
37
+
38
+ | Consideration | Use Opus/Large | Use Sonnet/Medium | Use Haiku/Small |
39
+ |---------------|---------------|-------------------|-----------------|
40
+ | Architecture | Yes | — | — |
41
+ | Complex features | Yes | — | — |
42
+ | Simple features | — | Yes | — |
43
+ | Code review | Yes | Yes | — |
44
+ | Documentation | — | Yes | — |
45
+ | Quick questions | — | — | Yes |
46
+ | Content filtering | — | — | Yes |
47
+
48
+ ## Prompt Library Index
49
+
50
+ | Category | Template | Location |
51
+ |----------|----------|----------|
52
+ | Feature build | feature-implementation.md | templates/workflows/ |
53
+ | Bug fix | bug-investigation.md | templates/workflows/ |
54
+ | Refactoring | refactoring.md | templates/workflows/ |
55
+ | Architecture | architecture-decision.md | templates/workflows/ |
56
+ | Spike | spike-exploration.md | templates/workflows/ |