@kw-yeh/vibeflow 4.11.22 → 4.11.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.
@@ -68,9 +68,31 @@ Add `scope` only when one area clearly owns the change.
68
68
  Issue link: if the argument or the branch name carries an issue reference (`#123`, `ABC-123`),
69
69
  put it in **Why** (`Closes #123` for a GitHub issue in this repo).
70
70
 
71
- ## 5. Create or update
72
-
73
- Write the body to a temp file, then:
71
+ ## 5. Screenshots and acceptance videos
72
+
73
+ - When `VIBEFLOW_ARTIFACTS_DIR` is set and nonempty, look there first for this change's screenshots
74
+ and acceptance videos, including subdirectories such as `visual-parity/run-*`. Select files that
75
+ actually show this branch's behavior; do not attach unrelated or stale evidence.
76
+ - Save new screenshots in a new subdirectory of `VIBEFLOW_ARTIFACTS_DIR` (for example
77
+ `pr/<unique-run>/`). Create it first, quote paths containing spaces, and preserve earlier evidence.
78
+ Keep final acceptance videos there too; recordings from visual-parity may remain in its run directory.
79
+ - Put temporary browser scripts, extra logs, PR body files and recording intermediates in
80
+ `VIBEFLOW_SCRATCH_DIR`. If it is unset or empty but the Artifact root exists, use its `scratch/`
81
+ subdirectory. If neither is available, use the agent's scratchpad or the system temp directory.
82
+ - When the Artifact variable is unset or empty (outside VibeFlow), use an existing evidence location
83
+ or the agent's scratchpad for new captures. Missing variables must not block the PR workflow;
84
+ an explicit user-specified path takes priority.
85
+ - **Upload screenshots and videos through the GitHub web UI only. Never commit them to the repo.**
86
+ Create or update the PR with `gh` as below, then use GitHub's attachment control in its description
87
+ or a comment. For an acceptance video, add a separate comment and upload the actual video there.
88
+ Wait for the upload to finish and confirm the resulting GitHub attachment link before submitting.
89
+ A local filesystem path is not an uploaded attachment. If no acceptance video exists, skip the
90
+ video comment. If the browser cannot upload or is not signed in, report that limitation and keep
91
+ the file in Artifacts; do not substitute a repository commit or claim the upload succeeded.
92
+
93
+ ## 6. Create or update
94
+
95
+ Write the body to a unique temp file in the scratch location above, then:
74
96
 
75
97
  ```bash
76
98
  gh pr create --draft --base <base> --title "<title>" --body-file <file>
@@ -17,6 +17,7 @@ description: 比對兩個已渲染網頁的樣式落差(新舊版對照 / 改
17
17
  2. **不要把報告全文讀進 context。** stdout 的摘要已含「最常出現的落差屬性」;需要細節時用 `grep` 撈特定屬性或 selector,不要 `Read` 整份。
18
18
  3. **不要逐項修。** 先看 stdout 的 top differing properties——落差通常是少數幾條系統性規則(一條 `margin-bottom`、一組 token)造成的,不是幾十個獨立問題。
19
19
  4. **改完重跑一次全量比對**,而不是只驗剛改的那一項。
20
+ 5. **先選輸出目錄。** 在 VibeFlow 中,驗收證據預設寫入 `VIBEFLOW_ARTIFACTS_DIR` 的子目錄,暫存工作檔寫入 `VIBEFLOW_SCRATCH_DIR`;不要留在 agent scratchpad,也不要 commit 截圖或影片。
20
21
 
21
22
  ## 前置
22
23
 
@@ -28,13 +29,43 @@ description: 比對兩個已渲染網頁的樣式落差(新舊版對照 / 改
28
29
  打到登入頁或拒絕頁時比對結果毫無意義——`matched` 異常地少就先檢查這個。
29
30
  - 新舊對照要同時起兩份 server(不同 port),各自當 `--ref` 與 `--local`。
30
31
 
32
+ ## 輸出目錄 — 每次驗收先執行
33
+
34
+ 以下為 Bash 範例,在同一個 shell 依序執行。路徑即使含空白也必須保留引號。
35
+ PowerShell 請依同一優先順序建立目錄、設定 `$env:PARITY_OUT`/`$env:PARITY_SCRATCH`,並在呼叫 Python 的 process 設定 `TMPDIR`;不要直接貼 Bash 語法。
36
+
37
+ ```bash
38
+ if [ -n "${VIBEFLOW_ARTIFACTS_DIR:-}" ]; then
39
+ mkdir -p "$VIBEFLOW_ARTIFACTS_DIR/visual-parity"
40
+ PARITY_OUT="$(mktemp -d "$VIBEFLOW_ARTIFACTS_DIR/visual-parity/run-XXXXXX")"
41
+ else
42
+ PARITY_OUT="$PWD"
43
+ fi
44
+
45
+ if [ -n "${VIBEFLOW_SCRATCH_DIR:-}" ]; then
46
+ mkdir -p "$VIBEFLOW_SCRATCH_DIR"
47
+ PARITY_SCRATCH="$(mktemp -d "$VIBEFLOW_SCRATCH_DIR/parity-XXXXXX")"
48
+ elif [ -n "${VIBEFLOW_ARTIFACTS_DIR:-}" ]; then
49
+ mkdir -p "$VIBEFLOW_ARTIFACTS_DIR/scratch"
50
+ PARITY_SCRATCH="$(mktemp -d "$VIBEFLOW_ARTIFACTS_DIR/scratch/parity-XXXXXX")"
51
+ else
52
+ PARITY_SCRATCH="$(mktemp -d)"
53
+ fi
54
+ export PARITY_OUT PARITY_SCRATCH
55
+ ```
56
+
57
+ - `PARITY_OUT`:截圖、像素 diff 圖(若另行產生)、最終影片、Markdown 報告及新建立的 `steps.json`。有 Artifact root 時每次初始化建立獨立子目錄,避免覆蓋之前的證據。
58
+ - `PARITY_SCRATCH`:額外 log、一次性的 Playwright 腳本、錄影與轉檔中間檔。下文的 `TMPDIR` 前綴只影響該次 Python process,讓錄影暫存目錄也使用此位置;若將 stdout/stderr 另存 log,寫在這裡。報告內仍保留 console/network 摘要。
59
+ - 兩個 VibeFlow 變數皆 unset 或空值時,報告、影片及 steps 沿用 cwd,暫存檔使用系統暫存目錄;只有 scratch 變數時也能獨立使用,不要求兩者同時存在。
60
+ - 使用者明確指定的輸出位置優先;既有 `--steps` 或 repo 內回歸測試不自動搬移。`parity.py` 本身不讀這兩個 VibeFlow 變數,直接使用舊命令的路徑語意不變。
61
+
31
62
  ## diff — 新舊頁面樣式落差
32
63
 
33
64
  ```bash
34
- python <skill-dir>/scripts/parity.py diff \
35
- --ref https://staging.example.com/faq/content?id=28473 \
36
- --local https://localhost:3000/faq/content?id=28473 \
37
- --out parity-diff.md
65
+ TMPDIR="$PARITY_SCRATCH" python "<skill-dir>/scripts/parity.py" diff \
66
+ --ref "https://staging.example.com/faq/content?id=28473" \
67
+ --local "https://localhost:3000/faq/content?id=28473" \
68
+ --out "$PARITY_OUT/parity-diff.md"
38
69
  ```
39
70
 
40
71
  元素配對:先套 `--map` 的手動對照,再以「標籤+文字」自動配對,最後以「純文字」補配(吸收 SPA→SSR 的標籤變化,例如 `<p>` 變 `<div>`)。
@@ -48,6 +79,7 @@ stdout 會回報四個數字:
48
79
 
49
80
  其他參數:`--width` / `--widths`、`--wait-selector`(等內容渲染完)、`--extra-wait`(動畫或延遲載入)。
50
81
  Exit code 1 表示有落差,0 表示完全一致。
82
+ 此模式比對 DOM/computed styles,不產生像素 diff 圖;需要像素級比對時另行執行,將兩張截圖及 diff 圖同樣存入 `PARITY_OUT`。
51
83
 
52
84
  ### --map:手動指定對照
53
85
 
@@ -66,30 +98,42 @@ DOM 結構差太多時(舊 iframe vs 新 SSR),用 JSON 補:
66
98
  ## responsive — 三種寬度 + 水平溢出
67
99
 
68
100
  ```bash
69
- python <skill-dir>/scripts/parity.py responsive \
70
- --ref <URL> --local <URL> --out parity-responsive.md
101
+ TMPDIR="$PARITY_SCRATCH" python "<skill-dir>/scripts/parity.py" responsive \
102
+ --ref "<ref-URL>" --local "<local-URL>" \
103
+ --out "$PARITY_OUT/parity-responsive.md"
71
104
  ```
72
105
 
73
106
  等同在 375 / 768 / 1440 各跑一次 diff,另外檢查 local 是否出現水平溢出(`scrollWidth > clientWidth`),這是 RWD 破版最常見的徵兆。
74
107
 
75
108
  ## flow — 互動驗收 + console/network 錯誤
76
109
 
77
- 用 JSON 描述步驟,不要每次現寫 Playwright:
110
+ 用 JSON 描述步驟,不要每次現寫 Playwright。以下範例以 Python 寫入實際的 screenshot 絕對路徑;請依受測頁面調整 URL、selector 與 assertion。
111
+ **JSON 不會展開 `$PARITY_OUT` 等 shell 變數**,不要將它們直接寫成 JSON path:
78
112
 
79
- ```json
80
- [
113
+ ```bash
114
+ python - <<'PY'
115
+ import json
116
+ import os
117
+ from pathlib import Path
118
+
119
+ out = Path(os.environ["PARITY_OUT"]).resolve()
120
+ steps = [
81
121
  {"action": "goto", "url": "https://localhost:3000/products"},
82
122
  {"action": "click", "selector": ".ba-free-download", "desc": "點 Free Download"},
83
123
  {"action": "wait", "selector": "[role=dialog]"},
84
124
  {"action": "expect_focused", "selector": "[role=dialog] input[type=email]", "desc": "focus 應落在 input 而非 close button"},
85
125
  {"action": "fill", "selector": "input[type=email]", "value": "a@b.com"},
86
126
  {"action": "click", "selector": "button[type=submit]"},
87
- {"action": "expect_text", "selector": "[role=dialog]", "value": "Check your email"}
127
+ {"action": "expect_text", "selector": "[role=dialog]", "value": "Check your email"},
128
+ {"action": "screenshot", "path": str(out / "parity-flow.png")}
88
129
  ]
130
+ (out / "steps.json").write_text(json.dumps(steps, ensure_ascii=False, indent=2), encoding="utf-8")
131
+ PY
89
132
  ```
90
133
 
91
134
  ```bash
92
- python <skill-dir>/scripts/parity.py flow --steps steps.json --out parity-flow.md
135
+ TMPDIR="$PARITY_SCRATCH" python "<skill-dir>/scripts/parity.py" flow \
136
+ --steps "$PARITY_OUT/steps.json" --out "$PARITY_OUT/parity-flow.md"
93
137
  ```
94
138
 
95
139
  可用 action:`goto` `click` `fill` `press` `wait` `expect_text` `expect_visible` `expect_focused` `screenshot`。
@@ -102,8 +146,9 @@ python <skill-dir>/scripts/parity.py flow --steps steps.json --out parity-flow.m
102
146
  截圖看不出 transition、loading、hover 這類會動的東西,用錄影:
103
147
 
104
148
  ```bash
105
- python <skill-dir>/scripts/parity.py flow \
106
- --steps steps.json --out parity-flow.md --video parity-flow.mp4
149
+ TMPDIR="$PARITY_SCRATCH" python "<skill-dir>/scripts/parity.py" flow \
150
+ --steps "$PARITY_OUT/steps.json" --out "$PARITY_OUT/parity-flow.md" \
151
+ --video "$PARITY_OUT/parity-flow.mp4"
107
152
  ```
108
153
 
109
154
  - 副檔名 `.mp4` 會在錄完後用 ffmpeg 轉成 H.264(QuickTime 直接開),中間的 webm 自動刪除。**ffmpeg 不存在時不會失敗**,保留 `.webm` 並在 stdout 提示。副檔名寫 `.webm` 則完全不轉檔。
@@ -112,8 +157,8 @@ python <skill-dir>/scripts/parity.py flow \
112
157
  - 影格率是 Playwright screencast 的 **25fps**,判斷「動畫有沒有做對」夠用;要判斷「掉不掉幀」不夠,那種要用 macOS `screencapture -v` 錄 60fps。
113
158
  - 影片路徑會同時寫進報告開頭與 stdout。
114
159
 
115
- 把 flow 的 JSON 存進專案(例如 `e2e/`),下次改版直接重跑,就是回歸測試。
160
+ 新建的驗收 JSON 預設留在 `PARITY_OUT`,下次可用其實際路徑重跑。只有使用者明確要求保留程式碼回歸測試時,才放入專案(例如 `e2e/`);截圖、影片與其他驗收證據仍留在 Artifact,不 commit。
116
161
 
117
162
  ## 維護
118
163
 
119
- 改過 `parity.py` 後跑 `python <skill-dir>/scripts/parity.py selftest`,會用內建 fixture 驗證配對與 diff 邏輯仍正確。
164
+ 改過 `parity.py` 後跑 `TMPDIR="$PARITY_SCRATCH" python "<skill-dir>/scripts/parity.py" selftest`,會用內建 fixture 驗證配對與 diff 邏輯仍正確。
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/CmjRpL2U0hpvYdNfT2wlC/_buildManifest.js" defer=""></script><script src="/_next/static/CmjRpL2U0hpvYdNfT2wlC/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"CmjRpL2U0hpvYdNfT2wlC","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/k4vs9Y-8Wd6zK6Ztl4X27/_buildManifest.js" defer=""></script><script src="/_next/static/k4vs9Y-8Wd6zK6Ztl4X27/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"k4vs9Y-8Wd6zK6Ztl4X27","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
package/dist/web/404.html CHANGED
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/CmjRpL2U0hpvYdNfT2wlC/_buildManifest.js" defer=""></script><script src="/_next/static/CmjRpL2U0hpvYdNfT2wlC/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"CmjRpL2U0hpvYdNfT2wlC","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/k4vs9Y-8Wd6zK6Ztl4X27/_buildManifest.js" defer=""></script><script src="/_next/static/k4vs9Y-8Wd6zK6Ztl4X27/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"k4vs9Y-8Wd6zK6Ztl4X27","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">VibeFlow</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/9296-f476f95a89709fef.js" defer=""></script><script src="/_next/static/chunks/pages/home-6422d9ccd1c4678c.js" defer=""></script><script src="/_next/static/CmjRpL2U0hpvYdNfT2wlC/_buildManifest.js" defer=""></script><script src="/_next/static/CmjRpL2U0hpvYdNfT2wlC/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div class="bg-background text-foreground"><div class="flex min-h-screen items-center justify-center bg-background text-base text-muted-foreground">載入中…</div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/home","query":{},"buildId":"CmjRpL2U0hpvYdNfT2wlC","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><link rel="manifest" href="/manifest.webmanifest" data-next-head=""/><meta name="theme-color" content="#0d1117" data-next-head=""/><title data-next-head="">VibeFlow</title><link rel="preload" href="/_next/static/css/f8f64877c884206d.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f8f64877c884206d.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-401e9322101b6533.js" defer=""></script><script src="/_next/static/chunks/9296-f476f95a89709fef.js" defer=""></script><script src="/_next/static/chunks/pages/home-6422d9ccd1c4678c.js" defer=""></script><script src="/_next/static/k4vs9Y-8Wd6zK6Ztl4X27/_buildManifest.js" defer=""></script><script src="/_next/static/k4vs9Y-8Wd6zK6Ztl4X27/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div class="bg-background text-foreground"><div class="flex min-h-screen items-center justify-center bg-background text-base text-muted-foreground">載入中…</div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/home","query":{},"buildId":"k4vs9Y-8Wd6zK6Ztl4X27","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kw-yeh/vibeflow",
3
- "version": "4.11.22",
3
+ "version": "4.11.23",
4
4
  "description": "Intent-driven local kanban for coding agents: git worktree per card, Web UI and TUI.",
5
5
  "license": "MIT",
6
6
  "author": "KW-Yeh",