@tw93/waza 3.25.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/LICENSE +21 -0
- package/README.md +206 -0
- package/package.json +35 -0
- package/rules/anti-patterns.md +38 -0
- package/rules/chinese.md +18 -0
- package/rules/durable-context.md +27 -0
- package/rules/english.md +14 -0
- package/scripts/build_metadata.py +360 -0
- package/scripts/check_routing_drift.py +82 -0
- package/scripts/dispatcher-template.md +43 -0
- package/scripts/dispatcher.md +53 -0
- package/scripts/package-skill.sh +71 -0
- package/scripts/packaging_filter.py +55 -0
- package/scripts/setup-rule.sh +109 -0
- package/scripts/setup-statusline.sh +127 -0
- package/scripts/skill_checks.py +483 -0
- package/scripts/skill_frontmatter.py +110 -0
- package/scripts/statusline.sh +321 -0
- package/scripts/validate_package.py +66 -0
- package/scripts/verify_skills.py +100 -0
- package/skills/RESOLVER.md +91 -0
- package/skills/check/SKILL.md +338 -0
- package/skills/check/agents/reviewer-architecture.md +39 -0
- package/skills/check/agents/reviewer-security.md +39 -0
- package/skills/check/references/persona-catalog.md +56 -0
- package/skills/check/references/project-context.md +107 -0
- package/skills/check/references/public-reply.md +14 -0
- package/skills/check/scripts/audit_signals.py +485 -0
- package/skills/check/scripts/run-tests.sh +19 -0
- package/skills/design/SKILL.md +134 -0
- package/skills/design/references/design-aesthetic-quality.md +67 -0
- package/skills/design/references/design-data-viz.md +34 -0
- package/skills/design/references/design-reference.md +278 -0
- package/skills/design/references/design-tokens.md +53 -0
- package/skills/design/references/design-traps.md +43 -0
- package/skills/health/SKILL.md +231 -0
- package/skills/health/agents/inspector-context.md +119 -0
- package/skills/health/agents/inspector-control.md +84 -0
- package/skills/health/agents/inspector-maintainability.md +55 -0
- package/skills/health/scripts/check-agent-context.sh +5 -0
- package/skills/health/scripts/check-doc-refs.sh +8 -0
- package/skills/health/scripts/check-maintainability.sh +8 -0
- package/skills/health/scripts/check-verifier-output.sh +5 -0
- package/skills/health/scripts/check_agent_context.py +407 -0
- package/skills/health/scripts/check_doc_refs.py +110 -0
- package/skills/health/scripts/check_maintainability.py +629 -0
- package/skills/health/scripts/check_verifier_output.py +116 -0
- package/skills/health/scripts/collect-data.sh +760 -0
- package/skills/hunt/SKILL.md +197 -0
- package/skills/hunt/references/failure-patterns.md +75 -0
- package/skills/hunt/references/ime-unicode.md +58 -0
- package/skills/hunt/references/logging-techniques.md +72 -0
- package/skills/hunt/references/rendering-debug.md +34 -0
- package/skills/learn/SKILL.md +128 -0
- package/skills/read/SKILL.md +108 -0
- package/skills/read/references/read-methods.md +110 -0
- package/skills/read/references/save-paths.md +33 -0
- package/skills/read/scripts/fetch.sh +105 -0
- package/skills/read/scripts/fetch_feishu.py +246 -0
- package/skills/read/scripts/fetch_local.py +218 -0
- package/skills/read/scripts/fetch_weixin.py +107 -0
- package/skills/think/SKILL.md +155 -0
- package/skills/write/SKILL.md +129 -0
- package/skills/write/references/write-en.md +197 -0
- package/skills/write/references/write-zh-bilingual.md +60 -0
- package/skills/write/references/write-zh-prose.md +48 -0
- package/skills/write/references/write-zh-release-notes.md +38 -0
- package/skills/write/references/write-zh.md +645 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Install a Waza rule into Claude Code (~/.claude/rules/<rule>.md) or Codex
|
|
3
|
+
# (~/.codex/AGENTS.md, wrapped in markers so re-runs replace the block).
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# setup-rule.sh <rule-name> [claude-code|codex]
|
|
7
|
+
#
|
|
8
|
+
# rule-name corresponds to a file at rules/<rule-name>.md in this repo. Marker
|
|
9
|
+
# label is derived from the rule slug (e.g. anti-patterns -> Anti-Patterns,
|
|
10
|
+
# english -> English Coaching), with explicit overrides for the established
|
|
11
|
+
# product names so existing AGENTS.md installs remain idempotent.
|
|
12
|
+
set -e
|
|
13
|
+
|
|
14
|
+
RULE="${1:-}"
|
|
15
|
+
TARGET="${2:-claude-code}"
|
|
16
|
+
WAZA_REF="${WAZA_REF:-v3.25.0}"
|
|
17
|
+
|
|
18
|
+
if [ -z "$RULE" ]; then
|
|
19
|
+
echo "Usage: setup-rule.sh <rule-name> [claude-code|codex]" >&2
|
|
20
|
+
echo "Examples: setup-rule.sh anti-patterns" >&2
|
|
21
|
+
echo " setup-rule.sh english codex" >&2
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
case "$RULE" in
|
|
26
|
+
*[!a-z0-9-]* | -* | *- | "")
|
|
27
|
+
echo "Error: rule-name must match [a-z0-9][a-z0-9-]*[a-z0-9]." >&2
|
|
28
|
+
exit 1
|
|
29
|
+
;;
|
|
30
|
+
esac
|
|
31
|
+
|
|
32
|
+
case "$WAZA_REF" in
|
|
33
|
+
main|v[0-9]*.[0-9]*.[0-9]*) ;;
|
|
34
|
+
*)
|
|
35
|
+
echo "Error: WAZA_REF must be main or a release tag like v3.24.0." >&2
|
|
36
|
+
exit 1
|
|
37
|
+
;;
|
|
38
|
+
esac
|
|
39
|
+
|
|
40
|
+
RAW="https://raw.githubusercontent.com/tw93/Waza/${WAZA_REF}/rules/${RULE}.md"
|
|
41
|
+
|
|
42
|
+
# Marker label = how the block appears in ~/.codex/AGENTS.md. Established names
|
|
43
|
+
# kept verbatim so existing installs keep matching their original start/end
|
|
44
|
+
# markers; new rules fall back to a Title Case rendering of the slug.
|
|
45
|
+
case "$RULE" in
|
|
46
|
+
english) MARKER_LABEL="English Coaching" ;;
|
|
47
|
+
anti-patterns) MARKER_LABEL="Anti-Patterns" ;;
|
|
48
|
+
*)
|
|
49
|
+
MARKER_LABEL="$(printf '%s' "$RULE" | tr '-' ' ' | awk '{ for (i=1;i<=NF;i++) $i = toupper(substr($i,1,1)) tolower(substr($i,2)); print }')"
|
|
50
|
+
;;
|
|
51
|
+
esac
|
|
52
|
+
|
|
53
|
+
if ! command -v curl >/dev/null 2>&1; then
|
|
54
|
+
echo "Error: curl is required but not installed." >&2
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
case "$TARGET" in
|
|
59
|
+
claude-code|claude)
|
|
60
|
+
mkdir -p "$HOME/.claude/rules"
|
|
61
|
+
curl -fsSL "$RAW" -o "$HOME/.claude/rules/${RULE}.md"
|
|
62
|
+
echo "Waza ${MARKER_LABEL} installed for Claude Code."
|
|
63
|
+
;;
|
|
64
|
+
|
|
65
|
+
codex)
|
|
66
|
+
if ! command -v python3 >/dev/null 2>&1; then
|
|
67
|
+
echo "Error: python3 is required but not installed." >&2
|
|
68
|
+
exit 1
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
mkdir -p "$HOME/.codex"
|
|
72
|
+
tmp="$(mktemp)"
|
|
73
|
+
trap 'rm -f "$tmp"' EXIT
|
|
74
|
+
curl -fsSL "$RAW" -o "$tmp"
|
|
75
|
+
|
|
76
|
+
# Inline Python: this script is installed via `curl | bash` (no companion
|
|
77
|
+
# .py file on the user's machine), so the AGENTS.md edit logic stays self-
|
|
78
|
+
# contained here. py_compile cannot syntax-check it; bash -n catches
|
|
79
|
+
# quoting bugs in the shell layer.
|
|
80
|
+
MARKER_LABEL="$MARKER_LABEL" python3 - "$tmp" "$HOME/.codex/AGENTS.md" <<'PYEOF'
|
|
81
|
+
import os
|
|
82
|
+
import sys
|
|
83
|
+
from pathlib import Path
|
|
84
|
+
|
|
85
|
+
label = os.environ["MARKER_LABEL"]
|
|
86
|
+
source = Path(sys.argv[1]).read_text().strip()
|
|
87
|
+
target = Path(sys.argv[2])
|
|
88
|
+
start = f"<!-- Waza {label}: start -->"
|
|
89
|
+
end = f"<!-- Waza {label}: end -->"
|
|
90
|
+
block = f"{start}\n{source}\n{end}\n"
|
|
91
|
+
text = target.read_text() if target.exists() else ""
|
|
92
|
+
|
|
93
|
+
if start in text and end in text:
|
|
94
|
+
before = text.split(start, 1)[0].rstrip()
|
|
95
|
+
after = text.split(end, 1)[1].lstrip()
|
|
96
|
+
text = f"{before}\n\n{block}\n{after}".rstrip() + "\n"
|
|
97
|
+
else:
|
|
98
|
+
text = text.rstrip() + "\n\n" + block
|
|
99
|
+
|
|
100
|
+
target.write_text(text)
|
|
101
|
+
PYEOF
|
|
102
|
+
echo "Waza ${MARKER_LABEL} installed for Codex."
|
|
103
|
+
;;
|
|
104
|
+
|
|
105
|
+
*)
|
|
106
|
+
echo "Usage: setup-rule.sh <rule-name> [claude-code|codex]" >&2
|
|
107
|
+
exit 1
|
|
108
|
+
;;
|
|
109
|
+
esac
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Install Waza statusline into Claude Code
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
CLAUDE_DIR="$HOME/.claude"
|
|
6
|
+
DEST="$CLAUDE_DIR/statusline.sh"
|
|
7
|
+
SETTINGS_FILE="$CLAUDE_DIR/settings.json"
|
|
8
|
+
WAZA_REF="${WAZA_REF:-v3.25.0}"
|
|
9
|
+
|
|
10
|
+
case "$WAZA_REF" in
|
|
11
|
+
main|v[0-9]*.[0-9]*.[0-9]*) ;;
|
|
12
|
+
*)
|
|
13
|
+
echo "Error: WAZA_REF must be main or a release tag like v3.24.0." >&2
|
|
14
|
+
exit 1
|
|
15
|
+
;;
|
|
16
|
+
esac
|
|
17
|
+
|
|
18
|
+
RAW="https://raw.githubusercontent.com/tw93/Waza/${WAZA_REF}/scripts/statusline.sh"
|
|
19
|
+
|
|
20
|
+
if ! command -v curl &>/dev/null; then
|
|
21
|
+
echo "Error: curl is required but not installed." >&2
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if ! command -v python3 &>/dev/null; then
|
|
26
|
+
echo "Error: python3 is required but not installed." >&2
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
if ! command -v jq &>/dev/null; then
|
|
31
|
+
if command -v brew &>/dev/null; then
|
|
32
|
+
echo "Installing jq via Homebrew..."
|
|
33
|
+
brew install jq
|
|
34
|
+
else
|
|
35
|
+
echo "Error: jq is required but not installed." >&2
|
|
36
|
+
echo " macOS: brew install jq" >&2
|
|
37
|
+
echo " Linux: sudo apt-get install jq or sudo dnf install jq" >&2
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
mkdir -p "$CLAUDE_DIR"
|
|
43
|
+
|
|
44
|
+
# Refuse to modify an invalid settings file. Overwriting it would drop unrelated keys.
|
|
45
|
+
if [ -f "$SETTINGS_FILE" ]; then
|
|
46
|
+
SETTINGS_FILE="$SETTINGS_FILE" python3 - <<'PYEOF'
|
|
47
|
+
import json
|
|
48
|
+
import os
|
|
49
|
+
import sys
|
|
50
|
+
|
|
51
|
+
path = os.environ["SETTINGS_FILE"]
|
|
52
|
+
try:
|
|
53
|
+
with open(path) as f:
|
|
54
|
+
json.load(f)
|
|
55
|
+
except Exception as exc:
|
|
56
|
+
print(f"Error: {path} is not valid JSON. Refusing to modify it.", file=sys.stderr)
|
|
57
|
+
print(f"Reason: {exc}", file=sys.stderr)
|
|
58
|
+
sys.exit(1)
|
|
59
|
+
PYEOF
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Check for existing statusLine (skip if already Waza)
|
|
63
|
+
EXISTING=$(SETTINGS_FILE="$SETTINGS_FILE" python3 -c "
|
|
64
|
+
import json, os
|
|
65
|
+
path = os.environ['SETTINGS_FILE']
|
|
66
|
+
if os.path.exists(path):
|
|
67
|
+
d = json.load(open(path))
|
|
68
|
+
sl = d.get('statusLine', {})
|
|
69
|
+
cmd = sl.get('command', '')
|
|
70
|
+
if cmd and cmd != 'bash ~/.claude/statusline.sh':
|
|
71
|
+
print(cmd)
|
|
72
|
+
" 2>/dev/null)
|
|
73
|
+
|
|
74
|
+
if [ -n "$EXISTING" ]; then
|
|
75
|
+
echo "Another statusline is already configured:"
|
|
76
|
+
echo " $EXISTING"
|
|
77
|
+
ans=""
|
|
78
|
+
prompted=0
|
|
79
|
+
if [ -t 0 ]; then
|
|
80
|
+
printf "Replace it with Waza statusline? [Y/n] "
|
|
81
|
+
if read -r ans; then prompted=1; fi
|
|
82
|
+
elif { printf "Replace it with Waza statusline? [Y/n] " >/dev/tty; } 2>/dev/null \
|
|
83
|
+
&& read -r ans </dev/tty 2>/dev/null; then
|
|
84
|
+
prompted=1
|
|
85
|
+
fi
|
|
86
|
+
if [ "$prompted" -eq 0 ]; then
|
|
87
|
+
echo "Non-interactive shell with no controlling TTY; keeping existing statusline."
|
|
88
|
+
echo "Re-run interactively (or set WAZA_REPLACE_STATUSLINE=1) to replace it."
|
|
89
|
+
if [ "${WAZA_REPLACE_STATUSLINE:-}" != "1" ]; then
|
|
90
|
+
exit 0
|
|
91
|
+
fi
|
|
92
|
+
ans="y"
|
|
93
|
+
fi
|
|
94
|
+
if [ "$ans" = "n" ] || [ "$ans" = "N" ]; then
|
|
95
|
+
echo "Skipped. Existing statusline kept."
|
|
96
|
+
exit 0
|
|
97
|
+
fi
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# Download statusline script (after any confirmation prompt)
|
|
101
|
+
curl -fsSL "$RAW" -o "$DEST"
|
|
102
|
+
chmod +x "$DEST"
|
|
103
|
+
|
|
104
|
+
# Write statusLine into ~/.claude/settings.json
|
|
105
|
+
SETTINGS_FILE="$SETTINGS_FILE" python3 - <<'PYEOF'
|
|
106
|
+
import json
|
|
107
|
+
import os
|
|
108
|
+
import tempfile
|
|
109
|
+
|
|
110
|
+
path = os.environ["SETTINGS_FILE"]
|
|
111
|
+
d = {}
|
|
112
|
+
if os.path.exists(path):
|
|
113
|
+
with open(path) as f:
|
|
114
|
+
d = json.load(f)
|
|
115
|
+
|
|
116
|
+
d["statusLine"] = {"type": "command", "command": "bash ~/.claude/statusline.sh"}
|
|
117
|
+
|
|
118
|
+
directory = os.path.dirname(path)
|
|
119
|
+
fd, tmp_path = tempfile.mkstemp(prefix="settings.", suffix=".json.tmp", dir=directory)
|
|
120
|
+
with os.fdopen(fd, "w") as f:
|
|
121
|
+
json.dump(d, f, indent=2)
|
|
122
|
+
f.write("\n")
|
|
123
|
+
os.replace(tmp_path, path)
|
|
124
|
+
PYEOF
|
|
125
|
+
|
|
126
|
+
echo "Waza statusline installed. Restart Claude Code to activate."
|
|
127
|
+
echo "Tip: if you see a 513 error after switching Claude accounts, remove the statusLine entry from ~/.claude/settings.json, restart Claude Code, then re-run this script."
|