@qijenchen/design-system 0.1.0-beta.56 → 0.1.0-beta.57
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.
|
@@ -36,7 +36,11 @@ CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""' 2>/dev/null)
|
|
|
36
36
|
[ "$TOOL" != "Bash" ] && exit 0
|
|
37
37
|
|
|
38
38
|
# Heuristic:detect `git push origin <branch>` patterns
|
|
39
|
-
|
|
39
|
+
# 2026-06-06 fix:要求 `git push` 出現在「命令邊界」(行首 / ; / && / || / $( ),
|
|
40
|
+
# 否則 `P='git push origin'` 賦值、`echo "git push origin"`、`grep 'git push origin'` 等
|
|
41
|
+
# 「字串裡提到 push」會誤觸發 → falls-back 到 current branch 吐 404 preview URL 注入 context。
|
|
42
|
+
# 命令邊界 = 真的在執行 push,字串提及 = 噪音。對齊「只在真推送時 relay deploy URL」root invariant。
|
|
43
|
+
if ! echo "$CMD" | grep -qE '(^|[;&|(])[[:space:]]*git[[:space:]]+push[[:space:]]+(-u[[:space:]]+)?origin\b'; then
|
|
40
44
|
exit 0
|
|
41
45
|
fi
|
|
42
46
|
|
|
@@ -48,6 +52,21 @@ fi
|
|
|
48
52
|
CWD=$(pwd)
|
|
49
53
|
URLS_FOUND=""
|
|
50
54
|
BRANCH=$(echo "$CMD" | grep -oE 'origin\s+\S+' | awk '{print $2}' | head -1)
|
|
55
|
+
# 2026-06-06 fix:refspec `src:dst` → 取 dst(`HEAD:main` → `main`),否則推導出 `HEAD:main--site` 404 URL
|
|
56
|
+
case "$BRANCH" in *:*) BRANCH="${BRANCH##*:}" ;; esac
|
|
57
|
+
# 2026-06-06 fix:`git push origin HEAD`(或 `@`)= symbolic ref 指向當前 branch → 解析成真 branch 名,
|
|
58
|
+
# 否則把字面 "HEAD" 當 branch 推導出 `HEAD--site` 404 URL(real push 常用此式,會誤吐)。
|
|
59
|
+
if [ "$BRANCH" = "HEAD" ] || [ "$BRANCH" = "@" ]; then
|
|
60
|
+
BRANCH=$(git -C "$CWD" branch --show-current 2>/dev/null || echo "")
|
|
61
|
+
fi
|
|
62
|
+
# 2026-06-06 fix:BRANCH 含非法 git ref 字元(" ' 空白 \ 等)→ 此命令只是「字串裡含 git push origin」
|
|
63
|
+
# (測試迴圈 / 文件 / echo),非真推送 → skip,避免把 `main"` 等垃圾推導成 404 URL 注入 context。
|
|
64
|
+
# git ref 合法字元集 ⊂ [A-Za-z0-9._/-];非此集 = 必為解析噪音(root guard,涵蓋 refspec/tag 之外的雜訊)。
|
|
65
|
+
if [ -n "$BRANCH" ] && ! echo "$BRANCH" | grep -qE '^[A-Za-z0-9._/-]+$'; then exit 0; fi
|
|
66
|
+
# 2026-06-06 fix:tag push(`v1.2.3` 等)不產 branch-preview / production deploy → skip,
|
|
67
|
+
# 否則把 tag 名當 branch 推導出 `v0.1.0-beta.56--site` 404 URL(release tag push 每次都誤吐)
|
|
68
|
+
if echo "$BRANCH" | grep -qE '^v[0-9]'; then exit 0; fi
|
|
69
|
+
if [ -n "$BRANCH" ] && git -C "$CWD" rev-parse --verify --quiet "refs/tags/$BRANCH" >/dev/null 2>&1; then exit 0; fi
|
|
51
70
|
[ -z "$BRANCH" ] && BRANCH=$(git -C "$CWD" branch --show-current 2>/dev/null || echo "main")
|
|
52
71
|
|
|
53
72
|
# v3 2026-05-27:curl HEAD verify URL before reporting(per user「你確定有做到」complaint)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for inject_deploy_url_after_push.sh
|
|
3
|
+
#
|
|
4
|
+
# 鎖住 2026-06-06 收斂的「只在真推送 + 真 branch 時 relay deploy URL」root invariant,
|
|
5
|
+
# 防 refspec / symbolic-ref / tag / 解析噪音 / 字串提及 等再吐 404 URL 進 context。
|
|
6
|
+
|
|
7
|
+
set -u
|
|
8
|
+
|
|
9
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
+
HOOK="$SCRIPT_DIR/../inject_deploy_url_after_push.sh"
|
|
11
|
+
[ -f "$HOOK" ] || { echo "FATAL: hook not found"; exit 1; }
|
|
12
|
+
|
|
13
|
+
PASS=0; FAIL=0; FAILED=""
|
|
14
|
+
|
|
15
|
+
# 建一個臨時 git repo(branch=feature-test)+ netlify.toml,讓 Detection 2 可達;
|
|
16
|
+
# HOME 指向空 temp 確保無 USER_OVERRIDE(hermetic,不碰真實機 deploy-targets.json)。
|
|
17
|
+
setup() {
|
|
18
|
+
TMP=$(mktemp -d)
|
|
19
|
+
mkdir -p "$TMP/home"
|
|
20
|
+
(
|
|
21
|
+
cd "$TMP" || exit 1
|
|
22
|
+
git init -q -b feature-test 2>/dev/null || { git init -q; git checkout -q -b feature-test; }
|
|
23
|
+
: > netlify.toml
|
|
24
|
+
git add -A 2>/dev/null
|
|
25
|
+
GIT_AUTHOR_NAME=t GIT_AUTHOR_EMAIL=t@t GIT_COMMITTER_NAME=t GIT_COMMITTER_EMAIL=t@t \
|
|
26
|
+
git commit -q -m init 2>/dev/null
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
teardown() { rm -rf "$TMP"; }
|
|
30
|
+
|
|
31
|
+
# run_hook <command> [event] [tool]
|
|
32
|
+
run_hook() {
|
|
33
|
+
local cmd="$1" ev="${2:-PostToolUse}" tool="${3:-Bash}" json
|
|
34
|
+
json=$(printf '{"hook_event_name":"%s","tool_name":"%s","tool_input":{"command":"%s"}}' "$ev" "$tool" "$cmd")
|
|
35
|
+
STDOUT=$( cd "$TMP" && HOME="$TMP/home" CLAUDE_PROJECT_DIR="$TMP" bash "$HOOK" <<<"$json" 2>&1 )
|
|
36
|
+
EXIT=$?
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
injected() { echo "$STDOUT" | grep -q "Deploy URLs auto-detected"; }
|
|
40
|
+
head_leaked() { echo "$STDOUT" | grep -qE 'HEAD(--|:|\))'; }
|
|
41
|
+
fn7() { echo "$STDOUT" | grep -q "feature-test" && ! head_leaked; }
|
|
42
|
+
fn8() { ! head_leaked; }
|
|
43
|
+
fn9() { echo "$STDOUT" | grep -q "feature-test"; }
|
|
44
|
+
|
|
45
|
+
check() { # <name> <expect: skip|fire> [extra-assert-fn]
|
|
46
|
+
local name="$1" expect="$2" extra="${3:-}"
|
|
47
|
+
local ok=1
|
|
48
|
+
if [ "$expect" = "skip" ]; then
|
|
49
|
+
{ [ "$EXIT" = "0" ] && ! injected; } || ok=0
|
|
50
|
+
else # fire
|
|
51
|
+
{ [ "$EXIT" = "0" ] && injected; } || ok=0
|
|
52
|
+
fi
|
|
53
|
+
if [ -n "$extra" ] && ! "$extra"; then ok=0; fi
|
|
54
|
+
if [ "$ok" = "1" ]; then
|
|
55
|
+
echo " PASS $name"; PASS=$((PASS+1))
|
|
56
|
+
else
|
|
57
|
+
echo " FAIL $name (exit=$EXIT, expect=$expect)"
|
|
58
|
+
echo " output=${STDOUT:0:240}"
|
|
59
|
+
FAIL=$((FAIL+1)); FAILED="${FAILED}\n - $name"
|
|
60
|
+
fi
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
setup
|
|
64
|
+
|
|
65
|
+
# 1. 非 PostToolUse event → skip
|
|
66
|
+
run_hook "git push origin feature-test" "UserPromptSubmit" "Bash"
|
|
67
|
+
check "1 non-PostToolUse event → skip" skip
|
|
68
|
+
|
|
69
|
+
# 2. 非 Bash tool → skip
|
|
70
|
+
run_hook "git push origin feature-test" "PostToolUse" "Edit"
|
|
71
|
+
check "2 non-Bash tool → skip" skip
|
|
72
|
+
|
|
73
|
+
# 3. tag push(v*)→ skip(原把 tag 名當 branch 推 404)
|
|
74
|
+
run_hook "git push origin v0.1.0-beta.56"
|
|
75
|
+
check "3 tag push → skip" skip
|
|
76
|
+
|
|
77
|
+
# 4. branch --delete(cleanup,非 deploy)→ skip
|
|
78
|
+
run_hook "git push origin --delete old-branch"
|
|
79
|
+
check "4 push --delete → skip" skip
|
|
80
|
+
|
|
81
|
+
# 5. 字串提及(賦值,非命令邊界)→ skip(command-boundary guard)
|
|
82
|
+
run_hook "P='git push origin'"
|
|
83
|
+
check "5 string-mention (assignment) → skip" skip
|
|
84
|
+
|
|
85
|
+
# 6. 解析噪音 / 非法 git ref 字元(~)→ skip(charset guard)
|
|
86
|
+
run_hook "git push origin foo~bar"
|
|
87
|
+
check "6 invalid-ref-charset branch → skip" skip
|
|
88
|
+
|
|
89
|
+
# 7. symbolic ref HEAD → fires + 解析成真 branch feature-test(非字面 HEAD)
|
|
90
|
+
run_hook "git push origin HEAD"
|
|
91
|
+
check "7 HEAD → fire + resolve to feature-test (no literal HEAD)" fire 'fn7'
|
|
92
|
+
|
|
93
|
+
# 8. refspec HEAD:main → 取 dst,不可洩漏字面 HEAD
|
|
94
|
+
run_hook "git push origin HEAD:main"
|
|
95
|
+
check "8 refspec HEAD:main → no HEAD leak" fire 'fn8'
|
|
96
|
+
|
|
97
|
+
# 9. positive control:真 branch push → fires(確保 skip 測試非因 hook 全壞而假過)
|
|
98
|
+
run_hook "git add -A && git push origin feature-test"
|
|
99
|
+
check "9 real branch push (positive control) → fire" fire 'fn9'
|
|
100
|
+
|
|
101
|
+
teardown
|
|
102
|
+
|
|
103
|
+
echo ""
|
|
104
|
+
echo "── Summary ──"
|
|
105
|
+
echo "PASS: $PASS / $((PASS+FAIL))"
|
|
106
|
+
if [ "$FAIL" -gt 0 ]; then
|
|
107
|
+
echo "FAIL: $FAIL"
|
|
108
|
+
printf "$FAILED\n"
|
|
109
|
+
exit 1
|
|
110
|
+
fi
|
|
111
|
+
echo "✅ All passed"
|
|
112
|
+
exit 0
|
package/ds-story-manifest.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"scripts/composition-fidelity-visual-diff.mjs",
|
|
8
8
|
"product-workspace apps/template/src/AllDsComponents.stories.tsx (ImportSmoke portal → DS Storybook link)"
|
|
9
9
|
],
|
|
10
|
-
"generatedAt": "2026-06-
|
|
10
|
+
"generatedAt": "2026-06-06T10:07:05.357Z"
|
|
11
11
|
},
|
|
12
12
|
"components": {
|
|
13
13
|
"accordion": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qijenchen/design-system",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.57",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "World-class design system — components, patterns, tokens, hooks (single source of truth for team distribution).",
|
|
6
6
|
"type": "module",
|