@windyroad/architect 0.21.0 → 0.21.1

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.
@@ -123,5 +123,5 @@
123
123
  }
124
124
  },
125
125
  "name": "wr-architect",
126
- "version": "0.21.0"
126
+ "version": "0.21.1"
127
127
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wr-architect",
3
- "version": "0.21.0",
3
+ "version": "0.21.1",
4
4
  "description": "Architecture decision enforcement for AI coding agents",
5
5
  "author": {
6
6
  "name": "Windy Road Technology",
@@ -65,9 +65,65 @@ if [ "${BYPASS_COMPENDIUM_REFRESH_GATE:-0}" = "1" ]; then
65
65
  exit 0
66
66
  fi
67
67
 
68
- # Resolve repo root so the git plumbing is path-stable.
69
- repo_root=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
70
- cd "$repo_root" || exit 0
68
+ # Resolve the checkout targeted by the command. Codex can execute a command in
69
+ # a different checkout from the hook process, so process cwd is only a legacy
70
+ # fallback when the event declares no checkout at all (P499 / RFC-069).
71
+ checkout=$(printf '%s' "$input" | python3 -c '
72
+ import json, re, shlex, sys
73
+
74
+ try:
75
+ data = json.load(sys.stdin)
76
+ tool = data.get("tool_input") or {}
77
+ for owner, key in ((tool, "cwd"), (tool, "workdir")):
78
+ if key in owner:
79
+ value = owner[key]
80
+ if not isinstance(value, str):
81
+ print(json.dumps({"declared": True, "path": ""}))
82
+ raise SystemExit
83
+ if value:
84
+ print(json.dumps({"declared": True, "path": value}))
85
+ raise SystemExit
86
+
87
+ try:
88
+ tokens = shlex.split(tool.get("command", ""))
89
+ except (TypeError, ValueError):
90
+ tokens = []
91
+ while tokens and re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*=.*", tokens[0]):
92
+ tokens.pop(0)
93
+ if len(tokens) >= 3 and tokens[0] == "cd" and tokens[2] == "&&":
94
+ print(json.dumps({"declared": True, "path": tokens[1]}))
95
+ raise SystemExit
96
+
97
+ if "cwd" in data:
98
+ value = data["cwd"]
99
+ if not isinstance(value, str):
100
+ print(json.dumps({"declared": True, "path": ""}))
101
+ elif value:
102
+ print(json.dumps({"declared": True, "path": value}))
103
+ else:
104
+ print(json.dumps({"declared": False, "path": ""}))
105
+ else:
106
+ print(json.dumps({"declared": False, "path": ""}))
107
+ except (AttributeError, json.JSONDecodeError):
108
+ print(json.dumps({"declared": True, "path": ""}))
109
+ ' 2>/dev/null) || checkout='{"declared":true,"path":""}'
110
+
111
+ deny_invalid_checkout() {
112
+ echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"architect-readme-pairing-check: the declared command checkout is not an absolute readable Git worktree. Retry the commit with an absolute workdir or an explicit leading cd to the intended checkout."}}' >&2
113
+ exit 2
114
+ }
115
+
116
+ if [ "$(printf '%s' "$checkout" | jq -r '.declared')" = "true" ]; then
117
+ declared=$(printf '%s' "$checkout" | jq -r '.path')
118
+ case "$declared" in
119
+ /*) ;;
120
+ *) deny_invalid_checkout ;;
121
+ esac
122
+ repo_root=$(git -C "$declared" rev-parse --show-toplevel 2>/dev/null) || deny_invalid_checkout
123
+ else
124
+ repo_root=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
125
+ fi
126
+ cd "$repo_root" || deny_invalid_checkout
71
127
 
72
128
  # Inspect the staged set. ADR bodies are docs/decisions/<NNN>-*.md (exclude the
73
129
  # README itself and the -history / -summary siblings).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/architect",
3
- "version": "0.21.0",
3
+ "version": "0.21.1",
4
4
  "description": "Architecture decision enforcement for AI coding agents",
5
5
  "bin": {
6
6
  "windyroad-architect": "./bin/install.mjs"