aw-ecc 1.4.21 → 1.4.23

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aw",
3
- "version": "1.4.21",
3
+ "version": "1.4.23",
4
4
  "description": "GoHighLevel Agentic Workspace Engine — agents, skills, commands, hooks, and rules for GHL development workflows.",
5
5
  "author": {
6
6
  "name": "GoHighLevel",
@@ -2,4 +2,5 @@
2
2
  set -euo pipefail
3
3
 
4
4
  # Reserved AW PostToolUse phase for Codex home routing.
5
+ cat >/dev/null || true
5
6
  exit 0
@@ -2,4 +2,5 @@
2
2
  set -euo pipefail
3
3
 
4
4
  # Reserved AW PreToolUse phase for Codex home routing.
5
+ cat >/dev/null || true
5
6
  exit 0
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
+ # Drain stdin because Codex writes a JSON payload even though this wrapper
5
+ # only returns AW session context and does not use the payload body.
6
+ cat >/dev/null || true
7
+
4
8
  TARGETS=(
5
9
  "$HOME/.aw_registry/platform/core/skills/using-aw-skills/hooks/session-start.sh"
6
10
  "$HOME/.aw/.aw_registry/platform/core/skills/using-aw-skills/hooks/session-start.sh"
@@ -2,4 +2,5 @@
2
2
  set -euo pipefail
3
3
 
4
4
  # Reserved AW Stop phase for Codex home routing.
5
+ cat >/dev/null || true
5
6
  exit 0
@@ -6,4 +6,5 @@ if [[ -f "$TARGET" ]]; then
6
6
  exec bash "$TARGET"
7
7
  fi
8
8
 
9
+ cat >/dev/null || true
9
10
  exit 0
@@ -2,7 +2,7 @@
2
2
  const { readStdin, runManagedShellHook } = require('./adapter');
3
3
 
4
4
  function emitAwPromptReminder(raw) {
5
- const result = runManagedShellHook('.cursor/hooks/shared/user-prompt-submit.sh', raw);
5
+ const result = runManagedShellHook('scripts/hooks/shared/user-prompt-submit.sh', raw);
6
6
  if (result.stderr) {
7
7
  process.stderr.write(result.stderr);
8
8
  }
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
+ # Drain stdin because harnesses can stream a JSON payload even though the AW
5
+ # session-start hook only emits routing context.
6
+ cat >/dev/null || true
7
+
4
8
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
5
9
  ROOT_DIR="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
6
10
 
@@ -1,155 +1,71 @@
1
1
  #!/usr/bin/env bash
2
- # UserPromptSubmit hook — inject a compact AW routing reminder plus scoped rule reminders
2
+ # UserPromptSubmit hook — emit a small, reliable AW routing reminder.
3
3
  #
4
- # Output is printed to stdout as a plain-text prompt reminder.
4
+ # This hook intentionally stays simple:
5
+ # - drain stdin so the harness can always finish writing payloads
6
+ # - remind the model to re-apply using-aw-skills
7
+ # - point at AGENTS.md and the canonical .aw_rules/platform tree when present
5
8
 
6
9
  set -euo pipefail
7
10
 
8
- INPUT=$(cat)
11
+ cat >/dev/null || true
9
12
 
10
- TMPFILE=$(mktemp) || exit 0
11
- trap 'rm -f "$TMPFILE"' EXIT
12
-
13
- PYTHON_CMD=""
14
- PYTHON_ARGS=()
15
-
16
- resolve_python_cmd() {
17
- if [ -n "${CLV2_PYTHON_CMD:-}" ] && command -v "$CLV2_PYTHON_CMD" >/dev/null 2>&1; then
18
- PYTHON_CMD="$CLV2_PYTHON_CMD"
19
- PYTHON_ARGS=()
20
- return 0
21
- fi
22
-
23
- if command -v python3 >/dev/null 2>&1; then
24
- PYTHON_CMD="python3"
25
- PYTHON_ARGS=()
26
- return 0
27
- fi
28
-
29
- if command -v python >/dev/null 2>&1; then
30
- PYTHON_CMD="python"
31
- PYTHON_ARGS=()
32
- return 0
33
- fi
34
-
35
- if command -v py >/dev/null 2>&1; then
36
- PYTHON_CMD="py"
37
- PYTHON_ARGS=(-3)
38
- return 0
39
- fi
40
-
41
- return 1
42
- }
43
-
44
- resolve_python_cmd || exit 0
45
-
46
- if [ "${#PYTHON_ARGS[@]}" -gt 0 ]; then
47
- echo "$INPUT" | "$PYTHON_CMD" "${PYTHON_ARGS[@]}" -c "
48
- import os, sys, json, re
49
- d = json.load(sys.stdin)
50
- cwd = d.get('cwd', '')
51
- prompt = d.get('prompt', '')
52
- cwd = re.sub(r'[^a-zA-Z0-9./_@:\\\\~\ -]', '', cwd)
53
- prompt = prompt[:500]
54
- stack_overlays_enabled = os.environ.get('AW_ENABLE_STACK_OVERLAY_RULES') == '1'
55
- print(f'CWD={cwd}')
56
- prompt_lower = prompt.lower()
57
- if any(k in prompt_lower for k in ['controller', 'service', 'module', '@body', 'nestjs', 'worker', 'dto']):
58
- print('DOMAIN=backend')
59
- if stack_overlays_enabled and any(k in prompt_lower for k in ['nestjs', '@body', '@controller', '@module', 'class-validator', 'dto']):
60
- print('STACK=nestjs')
61
- elif stack_overlays_enabled and any(k in prompt_lower for k in ['connectrpc', 'connect-go', 'buf.gen', 'protoc-gen-connect-go']):
62
- print('STACK=go-connect')
63
- elif any(k in prompt_lower for k in ['vue', 'component', 'template', 'frontend', '<script', 'nuxt']):
64
- print('DOMAIN=frontend')
65
- if stack_overlays_enabled and any(k in prompt_lower for k in ['nuxt', 'app.vue', 'useasyncdata', 'definepagemeta']):
66
- print('STACK=nuxt')
67
- elif stack_overlays_enabled and any(k in prompt_lower for k in ['vue', '<script', 'script setup', 'composable']):
68
- print('STACK=vue')
69
- elif any(k in prompt_lower for k in ['mongo', 'redis', 'schema', 'migration', 'database', 'index']):
70
- print('DOMAIN=data')
71
- elif any(k in prompt_lower for k in ['helm', 'terraform', 'kubernetes', 'k8s', 'deploy', 'dockerfile']):
72
- print('DOMAIN=infra')
73
- else:
74
- print('DOMAIN=universal')
75
- " > "$TMPFILE" 2>/dev/null || exit 0
13
+ # On Windows (Git Bash / MSYS), pwd returns POSIX paths (/tmp/...)
14
+ # but callers use native Windows paths (C:\Users\...).
15
+ # Convert via cygpath when available so paths match the caller's format.
16
+ if command -v cygpath >/dev/null 2>&1; then
17
+ CWD="$(cygpath -w "$(pwd)")"
76
18
  else
77
- echo "$INPUT" | "$PYTHON_CMD" -c "
78
- import os, sys, json, re
79
- d = json.load(sys.stdin)
80
- cwd = d.get('cwd', '')
81
- prompt = d.get('prompt', '')
82
- cwd = re.sub(r'[^a-zA-Z0-9./_@:\\\\~\ -]', '', cwd)
83
- prompt = prompt[:500]
84
- stack_overlays_enabled = os.environ.get('AW_ENABLE_STACK_OVERLAY_RULES') == '1'
85
- print(f'CWD={cwd}')
86
- prompt_lower = prompt.lower()
87
- if any(k in prompt_lower for k in ['controller', 'service', 'module', '@body', 'nestjs', 'worker', 'dto']):
88
- print('DOMAIN=backend')
89
- if stack_overlays_enabled and any(k in prompt_lower for k in ['nestjs', '@body', '@controller', '@module', 'class-validator', 'dto']):
90
- print('STACK=nestjs')
91
- elif stack_overlays_enabled and any(k in prompt_lower for k in ['connectrpc', 'connect-go', 'buf.gen', 'protoc-gen-connect-go']):
92
- print('STACK=go-connect')
93
- elif any(k in prompt_lower for k in ['vue', 'component', 'template', 'frontend', '<script', 'nuxt']):
94
- print('DOMAIN=frontend')
95
- if stack_overlays_enabled and any(k in prompt_lower for k in ['nuxt', 'app.vue', 'useasyncdata', 'definepagemeta']):
96
- print('STACK=nuxt')
97
- elif stack_overlays_enabled and any(k in prompt_lower for k in ['vue', '<script', 'script setup', 'composable']):
98
- print('STACK=vue')
99
- elif any(k in prompt_lower for k in ['mongo', 'redis', 'schema', 'migration', 'database', 'index']):
100
- print('DOMAIN=data')
101
- elif any(k in prompt_lower for k in ['helm', 'terraform', 'kubernetes', 'k8s', 'deploy', 'dockerfile']):
102
- print('DOMAIN=infra')
103
- else:
104
- print('DOMAIN=universal')
105
- " > "$TMPFILE" 2>/dev/null || exit 0
19
+ CWD="$(pwd)"
106
20
  fi
21
+ AGENTS_PATH="$CWD/AGENTS.md"
22
+ RULES_ROOT=""
23
+
24
+ for candidate in \
25
+ "$CWD/.aw_rules/platform" \
26
+ "$HOME/.aw_rules/platform" \
27
+ "$HOME/.aw/.aw_rules/platform"
28
+ do
29
+ if [ -d "$candidate" ]; then
30
+ RULES_ROOT="$candidate"
31
+ break
32
+ fi
33
+ done
107
34
 
108
- CWD="" DOMAIN="universal" STACK=""
109
- while IFS='=' read -r key value; do
110
- # Strip trailing \r from Windows Python CRLF output
111
- key="${key%$'\r'}"
112
- value="${value%$'\r'}"
113
- case "${key:-}" in
114
- CWD) CWD="$value" ;;
115
- DOMAIN) DOMAIN="$value" ;;
116
- STACK) STACK="$value" ;;
117
- esac
118
- done < "$TMPFILE"
119
-
120
- RULES_DIR=""
121
- DOMAIN_AGENTS=""
122
- STACK_AGENTS=""
35
+ RULE_REFS=()
123
36
 
124
- if [ -d "$CWD/.aw_registry/.aw_rules/platform" ]; then
125
- RULES_DIR="$CWD/.aw_registry/.aw_rules/platform"
126
- DOMAIN_AGENTS="$RULES_DIR/$DOMAIN/AGENTS.md"
127
- elif [ -d "$CWD/.aw_rules" ]; then
128
- RULES_DIR="$CWD/.aw_rules"
129
- DOMAIN_AGENTS="$RULES_DIR/$DOMAIN/AGENTS.md"
37
+ if [ -f "$AGENTS_PATH" ]; then
38
+ RULE_REFS+=("$AGENTS_PATH")
130
39
  fi
131
40
 
132
- [ -n "$RULES_DIR" ] || exit 0
133
- [ -f "$DOMAIN_AGENTS" ] || exit 0
134
-
135
- if [ -n "$STACK" ] && [ -f "$RULES_DIR/$DOMAIN/$STACK/AGENTS.md" ]; then
136
- STACK_AGENTS="$RULES_DIR/$DOMAIN/$STACK/AGENTS.md"
41
+ if [ -n "$RULES_ROOT" ]; then
42
+ if [ -f "$RULES_ROOT/universal/AGENTS.md" ]; then
43
+ RULE_REFS+=("$RULES_ROOT/universal/AGENTS.md")
44
+ fi
45
+ if [ -f "$RULES_ROOT/security/AGENTS.md" ]; then
46
+ RULE_REFS+=("$RULES_ROOT/security/AGENTS.md")
47
+ fi
48
+ RULE_SCOPE="Applicable domain rules live under $RULES_ROOT."
49
+ else
50
+ RULE_SCOPE="Applicable domain rules live under .aw_rules/platform when synced."
137
51
  fi
138
52
 
139
- DOMAIN_RULES=$(head -20 "$DOMAIN_AGENTS" 2>/dev/null || echo "")
140
- STACK_RULES=""
141
- if [ -n "$STACK_AGENTS" ]; then
142
- STACK_RULES=$(head -20 "$STACK_AGENTS" 2>/dev/null || echo "")
53
+ if [ "${#RULE_REFS[@]}" -gt 0 ]; then
54
+ RULE_PATHS=""
55
+ while IFS= read -r line; do
56
+ if [ -z "$RULE_PATHS" ]; then
57
+ RULE_PATHS="$line"
58
+ else
59
+ RULE_PATHS="$RULE_PATHS, $line"
60
+ fi
61
+ done < <(printf '%s\n' "${RULE_REFS[@]}" | awk '!seen[$0]++')
62
+ else
63
+ RULE_PATHS="AGENTS.md"
143
64
  fi
144
65
 
145
- RULE_BULLETS=$(printf '%s\n%s\n' "$DOMAIN_RULES" "$STACK_RULES" | grep -E "^\- .*(MUST|Never)" | awk '!seen[$0]++' | head -8 2>/dev/null || true)
146
-
147
- [ -z "$DOMAIN_RULES" ] && [ -z "$STACK_RULES" ] && exit 0
148
-
149
- cat << EOF
150
- [AW Router reminder] Re-apply using-aw-skills for this prompt and re-select the smallest correct AW route and stage skill before substantive work.
151
- [Rule reminder — $RULES_DIR/$DOMAIN${STACK_AGENTS:+/$STACK}] Active MUST rules for this scope. Follow them.
152
- ${RULE_BULLETS:-See $DOMAIN_AGENTS${STACK_AGENTS:+ and $STACK_AGENTS}}
66
+ cat <<EOF
67
+ [AW Router reminder] Re-apply using-aw-skills for this prompt and select the smallest correct AW route and stage skill before substantive work.
68
+ [Rules reminder] Start with $RULE_PATHS. Universal and security rules always apply. $RULE_SCOPE
153
69
  EOF
154
70
 
155
71
  exit 0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ecc-universal",
3
- "version": "1.4.21",
3
+ "version": "1.4.23",
4
4
  "description": "Everything Claude Code (ECC) plugin for OpenCode - agents, commands, hooks, and skills",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aw-ecc",
3
- "version": "1.4.21",
3
+ "version": "1.4.23",
4
4
  "description": "GoHighLevel Agentic Workspace Engine — forked from Everything Claude Code (ecc-universal)",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -2,7 +2,7 @@
2
2
  const { readStdin, runManagedShellHook } = require('./adapter');
3
3
 
4
4
  function emitAwPromptReminder(raw) {
5
- const result = runManagedShellHook('.cursor/hooks/shared/user-prompt-submit.sh', raw);
5
+ const result = runManagedShellHook('scripts/hooks/shared/user-prompt-submit.sh', raw);
6
6
  if (result.stderr) {
7
7
  process.stderr.write(result.stderr);
8
8
  }
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
+ # Drain stdin because harnesses can stream a JSON payload even though the AW
5
+ # session-start hook only emits routing context.
6
+ cat >/dev/null || true
7
+
4
8
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
5
9
  ROOT_DIR="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
6
10
 
@@ -1,155 +1,71 @@
1
1
  #!/usr/bin/env bash
2
- # UserPromptSubmit hook — inject a compact AW routing reminder plus scoped rule reminders
2
+ # UserPromptSubmit hook — emit a small, reliable AW routing reminder.
3
3
  #
4
- # Output is printed to stdout as a plain-text prompt reminder.
4
+ # This hook intentionally stays simple:
5
+ # - drain stdin so the harness can always finish writing payloads
6
+ # - remind the model to re-apply using-aw-skills
7
+ # - point at AGENTS.md and the canonical .aw_rules/platform tree when present
5
8
 
6
9
  set -euo pipefail
7
10
 
8
- INPUT=$(cat)
11
+ cat >/dev/null || true
9
12
 
10
- TMPFILE=$(mktemp) || exit 0
11
- trap 'rm -f "$TMPFILE"' EXIT
12
-
13
- PYTHON_CMD=""
14
- PYTHON_ARGS=()
15
-
16
- resolve_python_cmd() {
17
- if [ -n "${CLV2_PYTHON_CMD:-}" ] && command -v "$CLV2_PYTHON_CMD" >/dev/null 2>&1; then
18
- PYTHON_CMD="$CLV2_PYTHON_CMD"
19
- PYTHON_ARGS=()
20
- return 0
21
- fi
22
-
23
- if command -v python3 >/dev/null 2>&1; then
24
- PYTHON_CMD="python3"
25
- PYTHON_ARGS=()
26
- return 0
27
- fi
28
-
29
- if command -v python >/dev/null 2>&1; then
30
- PYTHON_CMD="python"
31
- PYTHON_ARGS=()
32
- return 0
33
- fi
34
-
35
- if command -v py >/dev/null 2>&1; then
36
- PYTHON_CMD="py"
37
- PYTHON_ARGS=(-3)
38
- return 0
39
- fi
40
-
41
- return 1
42
- }
43
-
44
- resolve_python_cmd || exit 0
45
-
46
- if [ "${#PYTHON_ARGS[@]}" -gt 0 ]; then
47
- echo "$INPUT" | "$PYTHON_CMD" "${PYTHON_ARGS[@]}" -c "
48
- import os, sys, json, re
49
- d = json.load(sys.stdin)
50
- cwd = d.get('cwd', '')
51
- prompt = d.get('prompt', '')
52
- cwd = re.sub(r'[^a-zA-Z0-9./_@:\\\\~\ -]', '', cwd)
53
- prompt = prompt[:500]
54
- stack_overlays_enabled = os.environ.get('AW_ENABLE_STACK_OVERLAY_RULES') == '1'
55
- print(f'CWD={cwd}')
56
- prompt_lower = prompt.lower()
57
- if any(k in prompt_lower for k in ['controller', 'service', 'module', '@body', 'nestjs', 'worker', 'dto']):
58
- print('DOMAIN=backend')
59
- if stack_overlays_enabled and any(k in prompt_lower for k in ['nestjs', '@body', '@controller', '@module', 'class-validator', 'dto']):
60
- print('STACK=nestjs')
61
- elif stack_overlays_enabled and any(k in prompt_lower for k in ['connectrpc', 'connect-go', 'buf.gen', 'protoc-gen-connect-go']):
62
- print('STACK=go-connect')
63
- elif any(k in prompt_lower for k in ['vue', 'component', 'template', 'frontend', '<script', 'nuxt']):
64
- print('DOMAIN=frontend')
65
- if stack_overlays_enabled and any(k in prompt_lower for k in ['nuxt', 'app.vue', 'useasyncdata', 'definepagemeta']):
66
- print('STACK=nuxt')
67
- elif stack_overlays_enabled and any(k in prompt_lower for k in ['vue', '<script', 'script setup', 'composable']):
68
- print('STACK=vue')
69
- elif any(k in prompt_lower for k in ['mongo', 'redis', 'schema', 'migration', 'database', 'index']):
70
- print('DOMAIN=data')
71
- elif any(k in prompt_lower for k in ['helm', 'terraform', 'kubernetes', 'k8s', 'deploy', 'dockerfile']):
72
- print('DOMAIN=infra')
73
- else:
74
- print('DOMAIN=universal')
75
- " > "$TMPFILE" 2>/dev/null || exit 0
13
+ # On Windows (Git Bash / MSYS), pwd returns POSIX paths (/tmp/...)
14
+ # but callers use native Windows paths (C:\Users\...).
15
+ # Convert via cygpath when available so paths match the caller's format.
16
+ if command -v cygpath >/dev/null 2>&1; then
17
+ CWD="$(cygpath -w "$(pwd)")"
76
18
  else
77
- echo "$INPUT" | "$PYTHON_CMD" -c "
78
- import os, sys, json, re
79
- d = json.load(sys.stdin)
80
- cwd = d.get('cwd', '')
81
- prompt = d.get('prompt', '')
82
- cwd = re.sub(r'[^a-zA-Z0-9./_@:\\\\~\ -]', '', cwd)
83
- prompt = prompt[:500]
84
- stack_overlays_enabled = os.environ.get('AW_ENABLE_STACK_OVERLAY_RULES') == '1'
85
- print(f'CWD={cwd}')
86
- prompt_lower = prompt.lower()
87
- if any(k in prompt_lower for k in ['controller', 'service', 'module', '@body', 'nestjs', 'worker', 'dto']):
88
- print('DOMAIN=backend')
89
- if stack_overlays_enabled and any(k in prompt_lower for k in ['nestjs', '@body', '@controller', '@module', 'class-validator', 'dto']):
90
- print('STACK=nestjs')
91
- elif stack_overlays_enabled and any(k in prompt_lower for k in ['connectrpc', 'connect-go', 'buf.gen', 'protoc-gen-connect-go']):
92
- print('STACK=go-connect')
93
- elif any(k in prompt_lower for k in ['vue', 'component', 'template', 'frontend', '<script', 'nuxt']):
94
- print('DOMAIN=frontend')
95
- if stack_overlays_enabled and any(k in prompt_lower for k in ['nuxt', 'app.vue', 'useasyncdata', 'definepagemeta']):
96
- print('STACK=nuxt')
97
- elif stack_overlays_enabled and any(k in prompt_lower for k in ['vue', '<script', 'script setup', 'composable']):
98
- print('STACK=vue')
99
- elif any(k in prompt_lower for k in ['mongo', 'redis', 'schema', 'migration', 'database', 'index']):
100
- print('DOMAIN=data')
101
- elif any(k in prompt_lower for k in ['helm', 'terraform', 'kubernetes', 'k8s', 'deploy', 'dockerfile']):
102
- print('DOMAIN=infra')
103
- else:
104
- print('DOMAIN=universal')
105
- " > "$TMPFILE" 2>/dev/null || exit 0
19
+ CWD="$(pwd)"
106
20
  fi
21
+ AGENTS_PATH="$CWD/AGENTS.md"
22
+ RULES_ROOT=""
23
+
24
+ for candidate in \
25
+ "$CWD/.aw_rules/platform" \
26
+ "$HOME/.aw_rules/platform" \
27
+ "$HOME/.aw/.aw_rules/platform"
28
+ do
29
+ if [ -d "$candidate" ]; then
30
+ RULES_ROOT="$candidate"
31
+ break
32
+ fi
33
+ done
107
34
 
108
- CWD="" DOMAIN="universal" STACK=""
109
- while IFS='=' read -r key value; do
110
- # Strip trailing \r from Windows Python CRLF output
111
- key="${key%$'\r'}"
112
- value="${value%$'\r'}"
113
- case "${key:-}" in
114
- CWD) CWD="$value" ;;
115
- DOMAIN) DOMAIN="$value" ;;
116
- STACK) STACK="$value" ;;
117
- esac
118
- done < "$TMPFILE"
119
-
120
- RULES_DIR=""
121
- DOMAIN_AGENTS=""
122
- STACK_AGENTS=""
35
+ RULE_REFS=()
123
36
 
124
- if [ -d "$CWD/.aw_registry/.aw_rules/platform" ]; then
125
- RULES_DIR="$CWD/.aw_registry/.aw_rules/platform"
126
- DOMAIN_AGENTS="$RULES_DIR/$DOMAIN/AGENTS.md"
127
- elif [ -d "$CWD/.aw_rules" ]; then
128
- RULES_DIR="$CWD/.aw_rules"
129
- DOMAIN_AGENTS="$RULES_DIR/$DOMAIN/AGENTS.md"
37
+ if [ -f "$AGENTS_PATH" ]; then
38
+ RULE_REFS+=("$AGENTS_PATH")
130
39
  fi
131
40
 
132
- [ -n "$RULES_DIR" ] || exit 0
133
- [ -f "$DOMAIN_AGENTS" ] || exit 0
134
-
135
- if [ -n "$STACK" ] && [ -f "$RULES_DIR/$DOMAIN/$STACK/AGENTS.md" ]; then
136
- STACK_AGENTS="$RULES_DIR/$DOMAIN/$STACK/AGENTS.md"
41
+ if [ -n "$RULES_ROOT" ]; then
42
+ if [ -f "$RULES_ROOT/universal/AGENTS.md" ]; then
43
+ RULE_REFS+=("$RULES_ROOT/universal/AGENTS.md")
44
+ fi
45
+ if [ -f "$RULES_ROOT/security/AGENTS.md" ]; then
46
+ RULE_REFS+=("$RULES_ROOT/security/AGENTS.md")
47
+ fi
48
+ RULE_SCOPE="Applicable domain rules live under $RULES_ROOT."
49
+ else
50
+ RULE_SCOPE="Applicable domain rules live under .aw_rules/platform when synced."
137
51
  fi
138
52
 
139
- DOMAIN_RULES=$(head -20 "$DOMAIN_AGENTS" 2>/dev/null || echo "")
140
- STACK_RULES=""
141
- if [ -n "$STACK_AGENTS" ]; then
142
- STACK_RULES=$(head -20 "$STACK_AGENTS" 2>/dev/null || echo "")
53
+ if [ "${#RULE_REFS[@]}" -gt 0 ]; then
54
+ RULE_PATHS=""
55
+ while IFS= read -r line; do
56
+ if [ -z "$RULE_PATHS" ]; then
57
+ RULE_PATHS="$line"
58
+ else
59
+ RULE_PATHS="$RULE_PATHS, $line"
60
+ fi
61
+ done < <(printf '%s\n' "${RULE_REFS[@]}" | awk '!seen[$0]++')
62
+ else
63
+ RULE_PATHS="AGENTS.md"
143
64
  fi
144
65
 
145
- RULE_BULLETS=$(printf '%s\n%s\n' "$DOMAIN_RULES" "$STACK_RULES" | grep -E "^\- .*(MUST|Never)" | awk '!seen[$0]++' | head -8 2>/dev/null || true)
146
-
147
- [ -z "$DOMAIN_RULES" ] && [ -z "$STACK_RULES" ] && exit 0
148
-
149
- cat << EOF
150
- [AW Router reminder] Re-apply using-aw-skills for this prompt and re-select the smallest correct AW route and stage skill before substantive work.
151
- [Rule reminder — $RULES_DIR/$DOMAIN${STACK_AGENTS:+/$STACK}] Active MUST rules for this scope. Follow them.
152
- ${RULE_BULLETS:-See $DOMAIN_AGENTS${STACK_AGENTS:+ and $STACK_AGENTS}}
66
+ cat <<EOF
67
+ [AW Router reminder] Re-apply using-aw-skills for this prompt and select the smallest correct AW route and stage skill before substantive work.
68
+ [Rules reminder] Start with $RULE_PATHS. Universal and security rules always apply. $RULE_SCOPE
153
69
  EOF
154
70
 
155
71
  exit 0
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
+ # Drain stdin because session-start emits static AW routing context and does
5
+ # not inspect the incoming payload.
6
+ cat >/dev/null || true
7
+
4
8
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
9
  LOCAL_ROOT=""
6
10
  SEARCH_ROOT="$SCRIPT_DIR"