@bookedsolid/reagent 0.7.2 → 0.11.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.
- package/README.md +277 -140
- package/agents/engineering/pr-voice-reviewer.md +229 -0
- package/agents/product-owner.md +152 -0
- package/agents/reagent-orchestrator.md +8 -0
- package/commands/pm-status.md +230 -0
- package/commands/review-pr.md +197 -0
- package/dist/cli/commands/catalyze/gap-detector.d.ts.map +1 -1
- package/dist/cli/commands/catalyze/gap-detector.js +1 -3
- package/dist/cli/commands/catalyze/gap-detector.js.map +1 -1
- package/dist/cli/commands/daemon/eject.d.ts +13 -0
- package/dist/cli/commands/daemon/eject.d.ts.map +1 -0
- package/dist/cli/commands/daemon/eject.js +74 -0
- package/dist/cli/commands/daemon/eject.js.map +1 -0
- package/dist/cli/commands/daemon/index.d.ts +5 -0
- package/dist/cli/commands/daemon/index.d.ts.map +1 -0
- package/dist/cli/commands/daemon/index.js +64 -0
- package/dist/cli/commands/daemon/index.js.map +1 -0
- package/dist/cli/commands/daemon/restart.d.ts +10 -0
- package/dist/cli/commands/daemon/restart.d.ts.map +1 -0
- package/dist/cli/commands/daemon/restart.js +20 -0
- package/dist/cli/commands/daemon/restart.js.map +1 -0
- package/dist/cli/commands/daemon/start.d.ts +2 -0
- package/dist/cli/commands/daemon/start.d.ts.map +1 -0
- package/dist/cli/commands/daemon/start.js +143 -0
- package/dist/cli/commands/daemon/start.js.map +1 -0
- package/dist/cli/commands/daemon/status.d.ts +2 -0
- package/dist/cli/commands/daemon/status.d.ts.map +1 -0
- package/dist/cli/commands/daemon/status.js +90 -0
- package/dist/cli/commands/daemon/status.js.map +1 -0
- package/dist/cli/commands/daemon/stop.d.ts +2 -0
- package/dist/cli/commands/daemon/stop.d.ts.map +1 -0
- package/dist/cli/commands/daemon/stop.js +73 -0
- package/dist/cli/commands/daemon/stop.js.map +1 -0
- package/dist/cli/commands/init/claude-hooks.d.ts +1 -1
- package/dist/cli/commands/init/claude-hooks.d.ts.map +1 -1
- package/dist/cli/commands/init/claude-hooks.js +10 -4
- package/dist/cli/commands/init/claude-hooks.js.map +1 -1
- package/dist/cli/commands/init/index.d.ts.map +1 -1
- package/dist/cli/commands/init/index.js +5 -1
- package/dist/cli/commands/init/index.js.map +1 -1
- package/dist/cli/commands/init/policy.d.ts.map +1 -1
- package/dist/cli/commands/init/policy.js +21 -0
- package/dist/cli/commands/init/policy.js.map +1 -1
- package/dist/cli/commands/init/types.d.ts +16 -0
- package/dist/cli/commands/init/types.d.ts.map +1 -1
- package/dist/cli/index.js +9 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/daemon-loader.d.ts +16 -0
- package/dist/config/daemon-loader.d.ts.map +1 -0
- package/dist/config/daemon-loader.js +76 -0
- package/dist/config/daemon-loader.js.map +1 -0
- package/dist/config/gateway-config.d.ts.map +1 -1
- package/dist/config/gateway-config.js +6 -0
- package/dist/config/gateway-config.js.map +1 -1
- package/dist/config/policy-loader.d.ts +27 -0
- package/dist/config/policy-loader.d.ts.map +1 -1
- package/dist/config/policy-loader.js +103 -10
- package/dist/config/policy-loader.js.map +1 -1
- package/dist/gateway/circuit-breaker.d.ts +60 -0
- package/dist/gateway/circuit-breaker.d.ts.map +1 -0
- package/dist/gateway/circuit-breaker.js +104 -0
- package/dist/gateway/circuit-breaker.js.map +1 -0
- package/dist/gateway/collision-detector.d.ts +31 -0
- package/dist/gateway/collision-detector.d.ts.map +1 -0
- package/dist/gateway/collision-detector.js +53 -0
- package/dist/gateway/collision-detector.js.map +1 -0
- package/dist/gateway/middleware/blocked-paths.js +2 -2
- package/dist/gateway/middleware/blocked-paths.js.map +1 -1
- package/dist/gateway/middleware/circuit-breaker.d.ts +12 -0
- package/dist/gateway/middleware/circuit-breaker.d.ts.map +1 -0
- package/dist/gateway/middleware/circuit-breaker.js +44 -0
- package/dist/gateway/middleware/circuit-breaker.js.map +1 -0
- package/dist/gateway/middleware/injection.d.ts +23 -0
- package/dist/gateway/middleware/injection.d.ts.map +1 -0
- package/dist/gateway/middleware/injection.js +129 -0
- package/dist/gateway/middleware/injection.js.map +1 -0
- package/dist/gateway/middleware/policy.js +2 -2
- package/dist/gateway/middleware/policy.js.map +1 -1
- package/dist/gateway/middleware/rate-limit.d.ts +13 -0
- package/dist/gateway/middleware/rate-limit.d.ts.map +1 -0
- package/dist/gateway/middleware/rate-limit.js +32 -0
- package/dist/gateway/middleware/rate-limit.js.map +1 -0
- package/dist/gateway/middleware/redact.d.ts.map +1 -1
- package/dist/gateway/middleware/redact.js +7 -0
- package/dist/gateway/middleware/redact.js.map +1 -1
- package/dist/gateway/middleware/result-size-cap.d.ts +14 -0
- package/dist/gateway/middleware/result-size-cap.d.ts.map +1 -0
- package/dist/gateway/middleware/result-size-cap.js +49 -0
- package/dist/gateway/middleware/result-size-cap.js.map +1 -0
- package/dist/gateway/native-tools.js +1 -1
- package/dist/gateway/native-tools.js.map +1 -1
- package/dist/gateway/rate-limiter.d.ts +47 -0
- package/dist/gateway/rate-limiter.d.ts.map +1 -0
- package/dist/gateway/rate-limiter.js +89 -0
- package/dist/gateway/rate-limiter.js.map +1 -0
- package/dist/gateway/server.d.ts.map +1 -1
- package/dist/gateway/server.js +27 -1
- package/dist/gateway/server.js.map +1 -1
- package/dist/gateway/tool-proxy.js +1 -1
- package/dist/gateway/tool-proxy.js.map +1 -1
- package/dist/types/daemon.d.ts +45 -0
- package/dist/types/daemon.d.ts.map +1 -0
- package/dist/types/daemon.js +2 -0
- package/dist/types/daemon.js.map +1 -0
- package/dist/types/gateway.d.ts +9 -0
- package/dist/types/gateway.d.ts.map +1 -1
- package/dist/types/policy.d.ts +1 -0
- package/dist/types/policy.d.ts.map +1 -1
- package/hooks/_lib/discord.sh +75 -0
- package/hooks/blocked-paths-enforcer.sh +0 -1
- package/hooks/changeset-security-gate.sh +143 -0
- package/hooks/commit-review-gate.sh +40 -10
- package/hooks/import-guard.sh +14 -0
- package/hooks/network-exfil-guard.sh +20 -2
- package/hooks/pr-issue-link-gate.sh +65 -0
- package/hooks/push-review-gate.sh +17 -2
- package/hooks/rate-limit-guard.sh +26 -2
- package/hooks/reagent-notify.sh +65 -0
- package/hooks/security-disclosure-gate.sh +146 -0
- package/husky/pre-push.sh +84 -0
- package/package.json +12 -2
- package/profiles/bst-internal.json +12 -2
- package/profiles/client-engagement.json +12 -2
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# hooks/reagent-notify.sh — post a one-off Discord notification about a repo event
|
|
3
|
+
#
|
|
4
|
+
# Useful for CI steps, post-merge automation, or manual release announcements.
|
|
5
|
+
# Sources the shared discord library so webhook resolution is consistent with
|
|
6
|
+
# the other hooks.
|
|
7
|
+
#
|
|
8
|
+
# Usage: hooks/reagent-notify.sh <event_type> <message>
|
|
9
|
+
# event_type: push | merge | release | alert
|
|
10
|
+
#
|
|
11
|
+
# Event-to-channel routing:
|
|
12
|
+
# push → dev
|
|
13
|
+
# merge → dev
|
|
14
|
+
# release → release
|
|
15
|
+
# alert → alert
|
|
16
|
+
# (anything else) → dev
|
|
17
|
+
|
|
18
|
+
set -uo pipefail
|
|
19
|
+
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
|
+
|
|
22
|
+
# shellcheck source=/dev/null
|
|
23
|
+
source "${SCRIPT_DIR}/_lib/discord.sh"
|
|
24
|
+
|
|
25
|
+
EVENT_TYPE="${1:-}"
|
|
26
|
+
MESSAGE="${2:-}"
|
|
27
|
+
|
|
28
|
+
if [ -z "$EVENT_TYPE" ] || [ -z "$MESSAGE" ]; then
|
|
29
|
+
printf 'Usage: %s <event_type> <message>\n' "$(basename "$0")" >&2
|
|
30
|
+
printf ' event_type: push | merge | release | alert\n' >&2
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Route event to the appropriate channel and pick a sensible default color
|
|
35
|
+
channel_type="dev"
|
|
36
|
+
color="blue"
|
|
37
|
+
|
|
38
|
+
case "$EVENT_TYPE" in
|
|
39
|
+
push)
|
|
40
|
+
channel_type="dev"
|
|
41
|
+
color="green"
|
|
42
|
+
;;
|
|
43
|
+
merge)
|
|
44
|
+
channel_type="dev"
|
|
45
|
+
color="green"
|
|
46
|
+
;;
|
|
47
|
+
release)
|
|
48
|
+
channel_type="release"
|
|
49
|
+
color="blue"
|
|
50
|
+
;;
|
|
51
|
+
alert)
|
|
52
|
+
channel_type="alert"
|
|
53
|
+
color="red"
|
|
54
|
+
;;
|
|
55
|
+
*)
|
|
56
|
+
channel_type="dev"
|
|
57
|
+
color="blue"
|
|
58
|
+
;;
|
|
59
|
+
esac
|
|
60
|
+
|
|
61
|
+
discord_notify "$channel_type" "$MESSAGE" "$color"
|
|
62
|
+
|
|
63
|
+
# Wait for the background curl before the script exits so the caller gets
|
|
64
|
+
# a clean exit code even in scripted pipelines.
|
|
65
|
+
wait
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# security-disclosure-gate.sh — PreToolUse: Bash
|
|
3
|
+
#
|
|
4
|
+
# Intercepts `gh issue create` commands that contain security-sensitive
|
|
5
|
+
# keywords and blocks them. Routing depends on REAGENT_DISCLOSURE_MODE:
|
|
6
|
+
#
|
|
7
|
+
# advisory (default) — redirect to GitHub Security Advisories (private)
|
|
8
|
+
# Use for public OSS repos
|
|
9
|
+
# issues — redirect to gh issue create with security + internal labels
|
|
10
|
+
# Use for permanently private client repos
|
|
11
|
+
# disabled — pass through (not recommended)
|
|
12
|
+
#
|
|
13
|
+
# Set REAGENT_DISCLOSURE_MODE in .reagent/policy.yaml (written to settings.json
|
|
14
|
+
# env by reagent init). Defaults to "advisory" when unset.
|
|
15
|
+
#
|
|
16
|
+
# Triggered by: PreToolUse — Bash tool
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
# shellcheck source=_lib/common.sh
|
|
21
|
+
source "$(dirname "$0")/_lib/common.sh"
|
|
22
|
+
|
|
23
|
+
check_halt
|
|
24
|
+
|
|
25
|
+
# Read disclosure mode — default to advisory
|
|
26
|
+
DISCLOSURE_MODE="${REAGENT_DISCLOSURE_MODE:-advisory}"
|
|
27
|
+
|
|
28
|
+
# Disabled mode: pass through entirely
|
|
29
|
+
if [[ "$DISCLOSURE_MODE" == "disabled" ]]; then
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
INPUT="$(cat)"
|
|
34
|
+
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
|
|
35
|
+
|
|
36
|
+
if [[ "$TOOL_NAME" != "Bash" ]]; then
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
|
|
41
|
+
|
|
42
|
+
# Only intercept gh issue create
|
|
43
|
+
if ! echo "$COMMAND" | grep -qE 'gh\s+issue\s+create'; then
|
|
44
|
+
exit 0
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
require_jq
|
|
48
|
+
|
|
49
|
+
# Security-sensitive keywords that should not appear in public issues —
|
|
50
|
+
# these terms suggest a vulnerability, exploit path, or bypass technique
|
|
51
|
+
SECURITY_PATTERNS=(
|
|
52
|
+
# Vulnerability classes
|
|
53
|
+
'bypass'
|
|
54
|
+
'exploit'
|
|
55
|
+
'injection'
|
|
56
|
+
'traversal'
|
|
57
|
+
'exfiltrat'
|
|
58
|
+
'escalat'
|
|
59
|
+
'privilege'
|
|
60
|
+
'rce'
|
|
61
|
+
'remote.code.exec'
|
|
62
|
+
'arbitrary.code'
|
|
63
|
+
'code.execution'
|
|
64
|
+
'zero.day'
|
|
65
|
+
'0day'
|
|
66
|
+
'CVE-'
|
|
67
|
+
'CVSS'
|
|
68
|
+
'GHSA-'
|
|
69
|
+
# Reagent-specific sensitive terms
|
|
70
|
+
'hook.bypass'
|
|
71
|
+
'HALT.bypass'
|
|
72
|
+
'redaction.bypass'
|
|
73
|
+
'policy.bypass'
|
|
74
|
+
'middleware.bypass'
|
|
75
|
+
'skip.*gate'
|
|
76
|
+
'evad'
|
|
77
|
+
# Credential/secret exposure
|
|
78
|
+
'secret.*leak'
|
|
79
|
+
'credential.*leak'
|
|
80
|
+
'token.*leak'
|
|
81
|
+
'key.*expos'
|
|
82
|
+
'expos.*secret'
|
|
83
|
+
# Prompt injection
|
|
84
|
+
'prompt.inject'
|
|
85
|
+
'jailbreak'
|
|
86
|
+
'jail.break'
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# Scan the full command text (title + body + flags) for sensitive patterns
|
|
90
|
+
FULL_TEXT=$(echo "$COMMAND" | tr '[:upper:]' '[:lower:]')
|
|
91
|
+
|
|
92
|
+
MATCHED_PATTERN=""
|
|
93
|
+
for PATTERN in "${SECURITY_PATTERNS[@]}"; do
|
|
94
|
+
if echo "$FULL_TEXT" | grep -qiE "$PATTERN"; then
|
|
95
|
+
MATCHED_PATTERN="$PATTERN"
|
|
96
|
+
break
|
|
97
|
+
fi
|
|
98
|
+
done
|
|
99
|
+
|
|
100
|
+
if [[ -z "$MATCHED_PATTERN" ]]; then
|
|
101
|
+
exit 0
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# ─── Route based on disclosure mode ──────────────────────────────────────────
|
|
105
|
+
|
|
106
|
+
if [[ "$DISCLOSURE_MODE" == "issues" ]]; then
|
|
107
|
+
# Private repo mode: redirect to labeled internal issue
|
|
108
|
+
json_output "block" \
|
|
109
|
+
"SECURITY DISCLOSURE GATE: This issue appears to describe a security finding (matched: '${MATCHED_PATTERN}').
|
|
110
|
+
|
|
111
|
+
This project is configured for PRIVATE disclosure (REAGENT_DISCLOSURE_MODE=issues).
|
|
112
|
+
|
|
113
|
+
CORRECT PATH for security findings in this private repo:
|
|
114
|
+
Use: gh issue create --label 'security,internal' --title '...' --body '...'
|
|
115
|
+
|
|
116
|
+
The 'security' and 'internal' labels keep this off public project boards and
|
|
117
|
+
mark it for maintainer-only triage. Do NOT use the public issue queue without
|
|
118
|
+
these labels for security findings.
|
|
119
|
+
|
|
120
|
+
If this is NOT a security finding, rephrase the title/body to avoid triggering
|
|
121
|
+
security patterns, then retry."
|
|
122
|
+
|
|
123
|
+
else
|
|
124
|
+
# Advisory mode (default): redirect to GitHub Security Advisories
|
|
125
|
+
json_output "block" \
|
|
126
|
+
"SECURITY DISCLOSURE GATE: This issue appears to describe a security vulnerability (matched: '${MATCHED_PATTERN}'). Do NOT create a public GitHub issue for security vulnerabilities.
|
|
127
|
+
|
|
128
|
+
CORRECT DISCLOSURE PATH:
|
|
129
|
+
1. Use GitHub Security Advisories (private):
|
|
130
|
+
gh api repos/{owner}/{repo}/security-advisories --method POST --input - <<'JSON'
|
|
131
|
+
{ \"summary\": \"...\", \"description\": \"...\", \"severity\": \"medium|high|critical\",
|
|
132
|
+
\"vulnerabilities\": [{\"package\": {\"name\": \"@pkg\", \"ecosystem\": \"npm\"}}] }
|
|
133
|
+
JSON
|
|
134
|
+
2. Or navigate to: Security tab → Advisories → 'Report a vulnerability'
|
|
135
|
+
3. Or email security@bookedsolid.tech (see SECURITY.md)
|
|
136
|
+
|
|
137
|
+
The finding will be publicly disclosed AFTER a patch is released (coordinated disclosure).
|
|
138
|
+
|
|
139
|
+
WHY: Public issues expose vulnerabilities before users can patch. This is enforced by the
|
|
140
|
+
security-disclosure-gate hook (REAGENT_DISCLOSURE_MODE=${DISCLOSURE_MODE}).
|
|
141
|
+
|
|
142
|
+
If this is NOT a security vulnerability, rephrase the issue to avoid triggering
|
|
143
|
+
security patterns, then retry."
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
exit 2
|
package/husky/pre-push.sh
CHANGED
|
@@ -64,12 +64,96 @@ run_gate "type-check" "TypeScript type check"
|
|
|
64
64
|
run_gate "test" "Test suite"
|
|
65
65
|
run_gate "build" "Build"
|
|
66
66
|
|
|
67
|
+
# Pack dry-run — validates the publish payload matches what CI would produce
|
|
68
|
+
# Always uses npm pack --dry-run regardless of $PKG_MANAGER: pnpm uses a
|
|
69
|
+
# different flag syntax and this gate mirrors the npm pack --dry-run step in CI.
|
|
70
|
+
if script_exists "build"; then
|
|
71
|
+
echo "pre-push: running Pack dry-run..."
|
|
72
|
+
if ! npm pack --dry-run > "$OUT" 2>&1; then
|
|
73
|
+
echo ""
|
|
74
|
+
echo "GATE FAILED: Pack dry-run"
|
|
75
|
+
cat "$OUT"
|
|
76
|
+
echo ""
|
|
77
|
+
FAILED="${FAILED} pack"
|
|
78
|
+
fi
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# Shellcheck — lint all hook and husky shell scripts if shellcheck is installed
|
|
82
|
+
if command -v shellcheck > /dev/null 2>&1; then
|
|
83
|
+
echo "pre-push: running Shellcheck on hook scripts..."
|
|
84
|
+
SHELL_SCRIPTS=$(find hooks/ husky/ -name "*.sh" 2>/dev/null | tr '\n' ' ')
|
|
85
|
+
if [ -n "$SHELL_SCRIPTS" ]; then
|
|
86
|
+
# shellcheck disable=SC2086
|
|
87
|
+
if ! shellcheck --shell=bash --severity=warning --exclude=SC1091,SC2034 $SHELL_SCRIPTS > "$OUT" 2>&1; then
|
|
88
|
+
echo ""
|
|
89
|
+
echo "GATE FAILED: Shellcheck"
|
|
90
|
+
cat "$OUT"
|
|
91
|
+
echo ""
|
|
92
|
+
FAILED="${FAILED} shellcheck"
|
|
93
|
+
fi
|
|
94
|
+
fi
|
|
95
|
+
else
|
|
96
|
+
echo "pre-push: shellcheck not installed — hook lint skipped (install: brew install shellcheck)"
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
# ── Optional: coverage threshold gate ─────────────────────────────────────────
|
|
100
|
+
# Enabled via .reagent/policy.yaml:
|
|
101
|
+
# coverage:
|
|
102
|
+
# enabled: true
|
|
103
|
+
# threshold: 80 # line/function/statement coverage percentage (branches: threshold - 10)
|
|
104
|
+
#
|
|
105
|
+
# Only runs if coverage.enabled is true AND the project has a test script.
|
|
106
|
+
POLICY_FILE=".reagent/policy.yaml"
|
|
107
|
+
COVERAGE_ENABLED="false"
|
|
108
|
+
COVERAGE_THRESHOLD=80
|
|
109
|
+
|
|
110
|
+
if [ -f "$POLICY_FILE" ]; then
|
|
111
|
+
# Extract coverage.enabled — look for "enabled: true" within the coverage block
|
|
112
|
+
if awk '/^coverage:/{in_block=1} in_block && /enabled: true/{found=1; exit} in_block && /^[^ ]/{in_block=0}' "$POLICY_FILE" | grep -q "enabled: true" 2>/dev/null || \
|
|
113
|
+
grep -A5 "^coverage:" "$POLICY_FILE" 2>/dev/null | grep -q "enabled: true"; then
|
|
114
|
+
COVERAGE_ENABLED="true"
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
# Extract coverage.threshold (default 80)
|
|
118
|
+
# The || true prevents set -euo pipefail from exiting when coverage: block is absent
|
|
119
|
+
THRESHOLD_LINE=$(grep -A5 "^coverage:" "$POLICY_FILE" 2>/dev/null | grep "threshold:" | head -1) || true
|
|
120
|
+
if [ -n "$THRESHOLD_LINE" ]; then
|
|
121
|
+
EXTRACTED=$(echo "$THRESHOLD_LINE" | awk '{print $2}' | tr -d '"' | tr -d "'")
|
|
122
|
+
if [ -n "$EXTRACTED" ] && [ "$EXTRACTED" -eq "$EXTRACTED" ] 2>/dev/null; then
|
|
123
|
+
COVERAGE_THRESHOLD="$EXTRACTED"
|
|
124
|
+
fi
|
|
125
|
+
fi
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
if [ "$COVERAGE_ENABLED" = "true" ] && script_exists "test"; then
|
|
129
|
+
echo "pre-push: running Coverage threshold (≥${COVERAGE_THRESHOLD}%)..."
|
|
130
|
+
if ! COVERAGE_THRESHOLD="$COVERAGE_THRESHOLD" $PKG_MANAGER run test -- --coverage > "$OUT" 2>&1; then
|
|
131
|
+
echo ""
|
|
132
|
+
echo "GATE FAILED: Coverage threshold (${COVERAGE_THRESHOLD}%)"
|
|
133
|
+
cat "$OUT"
|
|
134
|
+
echo ""
|
|
135
|
+
FAILED="${FAILED} coverage"
|
|
136
|
+
fi
|
|
137
|
+
fi
|
|
138
|
+
|
|
67
139
|
# ── Report ────────────────────────────────────────────────────────────────────
|
|
140
|
+
HOOKS_LIB="$(git rev-parse --show-toplevel 2>/dev/null)/hooks/_lib/discord.sh"
|
|
141
|
+
|
|
68
142
|
if [ -n "$FAILED" ]; then
|
|
69
143
|
echo "pre-push: FAILED gates:${FAILED}"
|
|
70
144
|
echo "All quality gates must pass before push. Fix failures and retry."
|
|
145
|
+
if [ -f "$HOOKS_LIB" ]; then
|
|
146
|
+
# shellcheck source=/dev/null
|
|
147
|
+
source "$HOOKS_LIB"
|
|
148
|
+
discord_notify "alert" "Push BLOCKED -- gate failures: \`${FAILED}\` on \`$(git rev-parse --abbrev-ref HEAD 2>/dev/null)\`" "red"
|
|
149
|
+
fi
|
|
71
150
|
exit 1
|
|
72
151
|
fi
|
|
73
152
|
|
|
74
153
|
echo "pre-push: all quality gates passed"
|
|
154
|
+
if [ -f "$HOOKS_LIB" ]; then
|
|
155
|
+
# shellcheck source=/dev/null
|
|
156
|
+
source "$HOOKS_LIB"
|
|
157
|
+
discord_notify "dev" "Pre-push gates passed on \`$(git rev-parse --abbrev-ref HEAD 2>/dev/null)\`" "green"
|
|
158
|
+
fi
|
|
75
159
|
exit 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bookedsolid/reagent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Zero-trust MCP gateway — policy enforcement, secret redaction, and audit logging for AI-assisted projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Booked Solid Technology <oss@bookedsolid.tech> (https://bookedsolid.tech)",
|
|
@@ -52,12 +52,21 @@
|
|
|
52
52
|
"changeset": "changeset",
|
|
53
53
|
"changeset:version": "changeset version",
|
|
54
54
|
"changeset:publish": "changeset publish",
|
|
55
|
+
"daemon:start": "mkdir -p ~/.reagent && nohup ./daemon/target/release/reagent-daemon > ~/.reagent/daemon.log 2>&1 & echo $! > ~/.reagent/daemon.pid && echo \"reagent daemon started (PID $(cat ~/.reagent/daemon.pid))\"",
|
|
56
|
+
"daemon:stop": "PID=$(cat ~/.reagent/daemon.pid 2>/dev/null); if [[ \"$PID\" =~ ^[0-9]+$ ]]; then kill -- \"$PID\" 2>/dev/null && rm -f ~/.reagent/daemon.pid && echo \"reagent daemon stopped\" || echo \"reagent daemon was not running\"; else echo \"reagent daemon was not running\"; fi",
|
|
57
|
+
"daemon:status": "[ -f ~/.reagent/daemon.pid ] && kill -0 $(cat ~/.reagent/daemon.pid) 2>/dev/null && echo \"running (PID $(cat ~/.reagent/daemon.pid))\" || echo \"not running\"",
|
|
58
|
+
"daemon:logs": "tail -f ~/.reagent/daemon.log",
|
|
59
|
+
"daemon:eject": "pkill -KILL -f reagent-daemon 2>/dev/null; rm -f ~/.reagent/daemon.pid; echo \"ejected\"",
|
|
60
|
+
"daemon:restart": "reagent daemon restart",
|
|
61
|
+
"daemon:build": "cargo build --release --manifest-path daemon/Cargo.toml",
|
|
55
62
|
"lint": "eslint .",
|
|
56
63
|
"format": "prettier --write .",
|
|
57
64
|
"format:check": "prettier --check .",
|
|
58
65
|
"test": "vitest run",
|
|
59
66
|
"test:watch": "vitest",
|
|
60
|
-
"type-check": "tsc --noEmit"
|
|
67
|
+
"type-check": "tsc --noEmit",
|
|
68
|
+
"docs:dev": "cd docs && npm run dev",
|
|
69
|
+
"docs:build": "cd docs && npm run build"
|
|
61
70
|
},
|
|
62
71
|
"keywords": [
|
|
63
72
|
"claude",
|
|
@@ -78,6 +87,7 @@
|
|
|
78
87
|
"@types/node": "^25.5.2",
|
|
79
88
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
80
89
|
"@typescript-eslint/parser": "^8.0.0",
|
|
90
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
81
91
|
"eslint": "^10.2.0",
|
|
82
92
|
"husky": "^9.1.7",
|
|
83
93
|
"prettier": "^3.8.1",
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
"preflightCmd": "pnpm preflight",
|
|
19
19
|
"attributionRule": "Do NOT include AI attribution in commits, PR bodies, code comments, or any content. When block_ai_attribution is enabled in .reagent/policy.yaml, the commit-msg hook REJECTS commits containing structural AI attribution (Co-Authored-By with AI names, 'Generated with [Tool]' footers, etc.). The attribution-advisory hook also blocks gh pr create/edit and git commit commands with attribution. You must remove all attribution markers before committing — the hooks will NOT silently fix them."
|
|
20
20
|
},
|
|
21
|
+
"security": {
|
|
22
|
+
"disclosureMode": "advisory"
|
|
23
|
+
},
|
|
21
24
|
"claudeHooks": {
|
|
22
25
|
"PreToolUse": [
|
|
23
26
|
{
|
|
@@ -27,12 +30,19 @@
|
|
|
27
30
|
"env-file-protection",
|
|
28
31
|
"dependency-audit-gate",
|
|
29
32
|
"commit-review-gate",
|
|
30
|
-
"push-review-gate"
|
|
33
|
+
"push-review-gate",
|
|
34
|
+
"security-disclosure-gate",
|
|
35
|
+
"pr-issue-link-gate"
|
|
31
36
|
]
|
|
32
37
|
},
|
|
33
38
|
{
|
|
34
39
|
"matcher": "Write|Edit",
|
|
35
|
-
"hooks": [
|
|
40
|
+
"hooks": [
|
|
41
|
+
"secret-scanner",
|
|
42
|
+
"settings-protection",
|
|
43
|
+
"blocked-paths-enforcer",
|
|
44
|
+
"changeset-security-gate"
|
|
45
|
+
]
|
|
36
46
|
},
|
|
37
47
|
{
|
|
38
48
|
"matcher": "Bash",
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
"preflightCmd": "pnpm preflight",
|
|
19
19
|
"attributionRule": "Do NOT include AI attribution in commits, PR bodies, code comments, or any content. When block_ai_attribution is enabled in .reagent/policy.yaml, the commit-msg hook REJECTS commits containing structural AI attribution (Co-Authored-By with AI names, 'Generated with [Tool]' footers, etc.). The attribution-advisory hook also blocks gh pr create/edit and git commit commands with attribution. You must remove all attribution markers before committing — the hooks will NOT silently fix them."
|
|
20
20
|
},
|
|
21
|
+
"security": {
|
|
22
|
+
"disclosureMode": "issues"
|
|
23
|
+
},
|
|
21
24
|
"claudeHooks": {
|
|
22
25
|
"PreToolUse": [
|
|
23
26
|
{
|
|
@@ -27,12 +30,19 @@
|
|
|
27
30
|
"env-file-protection",
|
|
28
31
|
"dependency-audit-gate",
|
|
29
32
|
"commit-review-gate",
|
|
30
|
-
"push-review-gate"
|
|
33
|
+
"push-review-gate",
|
|
34
|
+
"security-disclosure-gate",
|
|
35
|
+
"pr-issue-link-gate"
|
|
31
36
|
]
|
|
32
37
|
},
|
|
33
38
|
{
|
|
34
39
|
"matcher": "Write|Edit",
|
|
35
|
-
"hooks": [
|
|
40
|
+
"hooks": [
|
|
41
|
+
"secret-scanner",
|
|
42
|
+
"settings-protection",
|
|
43
|
+
"blocked-paths-enforcer",
|
|
44
|
+
"changeset-security-gate"
|
|
45
|
+
]
|
|
36
46
|
},
|
|
37
47
|
{
|
|
38
48
|
"matcher": "Bash",
|