v0.37.0
[0.37.0] - 2026-09-14
Highlight: LP(https://kewton.github.io/CommandMate/ )を「証拠・視覚・家具」で作り直した(Epic #2548)。hero をゲート行つきのセッション一覧に差し替えて "gate" =宣言したコマンドの exit code を図で示し、実測の Measured 表・「One agent leads」節・FAQ 8 問・通信範囲を 3 ノードの図で示す Trust 節・Docs / Changelog への nav・版行・
llms.txtを足した。節を足しても長くならないよう重複を畳み、同じ手法で測ったページの高さは 1280×900 で 10,528 → 10,469px、390×844 で 17,989 → 15,942px。デモ動画は画面に入ってから再生するようにし、初回ロードの.mp4リクエストを 5 本(3.0 MB)から 0 本にした。通信範囲の表現は実装に合わせて README / LP とも改めた(テレメトリ無し・機能ごとの通信を列挙)。
Added
- feat(website): LP の「What it does not do」の直後に FAQ 節(
<section class="section" id="faq">、ネイティブの<details>/<summary>× 8)を置き、問と答をdocs/design/public-messaging.md§13 のfaq:enから逐語・同順でコピーした (#2553): 見出しは §13 の節名と同じFAQ(§13 の表の外の文言はこの 1 語だけ。"Frequently" と書くと未計測の頻度の主張になるので略語のまま)。答の code span(.commandmate/verify.yaml・commandmate wait --verify・21/20/0・verify history・commandmate remote)は<code>。スクリプトは足しておらず(main.js無変更)、開閉はブラウザ標準の Enter / Space。nav ・ footer のアンカーは足していない。website/styles.cssは.limitsの規則の直後に/* FAQ (#2553) */…/* /FAQ (#2553) */で囲んだ 1 ブロック: 48rem の 1 列、項目ごとの罫線、既定の三角を消して CSS 描画のシェブロン(transform 0.15s)、summaryはグローバルのフォーカスリング(a・button・[tabindex]のみ)に入らないので:focus-visibleを足した。prefers-reduced-motion: reduceではページ全体の規則が transition を 0.01ms に縮めるだけなので、#faq・#faq::before・#faq::after・#faq *・#faq *::before・#faq *::afterにtransition: none !importantを置いた(section の class は全節共通のため id で指定)。tests/unit/website/landing-page.test.tsにdescribe('Issue #2553: FAQ')1 ブロック 9 件(95 → 104、既存の定数・関数は無変更でtableRows・prose・textを再利用): §13 のマーカーの中が 1〜8 の番号つき 3 列であること ・ 問と答の LP との逐語一致(順序込み・双方向の等値)・ 答ごとの code span が<code>であること ・#limitsの直後で間に section が無いこと ・<details>と<summary>が 8 つずつで summary に role / tabindex / onclick が無く main.js が FAQ や details / summary を掴まないこと ・ header にアンカーが無いこと ・ FAQ の本文にloopとthe onlyが無いこと(ページ全体の §11b 走査では The loop 節があるので免除されている 2 語)・ FAQ の CSS がブロックの外に無いこと ・ ブロック内で transition を宣言した規則がすべて reduced-motion でnoneになること。変異注入(19 通り、各回ファイルを復元してgit statusで無変更を確認)はすべて赤: §13 Q1 の答decides→decided(受入条件の「§13 側の答を 1 文字変える」、逐語一致テストが赤)・ §13 Q3 の問から?を削除 ・ §13 Q8 の答に.を追加 ・ §13 Q2 の21の backtick を外す(code span テスト)・ マーカー名faq:en→faq-en(4 件赤)・ LP Q1 のis not→isn't・ LP Q5 の<code>を外す ・ summary にtabindex="0"・ nav にhref="#faq"(#2552 の nav テスト 2 件も赤)・ 9 問目を追加 ・ 答にthe only・ 答にRemote Control(既存の禁止語走査も赤)・ reduced-motion の上書きを削除 ・ 上書きから::afterを外す(シェブロンが残る)・ 上書きをtransition-duration: 0.01msに変える ・ FAQ の規則をブロック外に 1 つ ・ Q4 と Q5 の順序入れ替え ・ FAQ 節をギャラリーの後ろへ移動 ・ main.js にquerySelectorAll("details")。禁止語 0(Remote Control含む)・ §11b の言えないこと 0 は既存のwebsite/**走査が緑。表示確認は CommandMate サーバを起動せずnode_modules/playwrightの headless Chromium でfile://を開いた: 1280×800 ・ 390×844 × ライト / ダークの 4 通りで閉 / Q2 と Q5 を開いた状態 / キーボードで Q3 を開いた状態をdev-reports/issue/2553/に撮影し、4 通りともscrollWidth=innerWidth、#faq配下で右端が viewport を越える要素 0。キーボードは#with-without .table-scrollから Tab → 1 問目の summary にフォーカス、Enter で開く → Enter で閉じる → Space で開く → Tab で 2 問目 → Space で開く → Space で閉じる(details.openを毎回確認)、フォーカスリングはsolid 2pxの--accent。reducedMotion: 'no-preference'ではシェブロンの::afterがtransform 0.15s(#faq配下で transition を持つのはこれだけ)、'reduce'ではnone 0sで、#faqとその全要素・::before/::afterに duration > 0 の transition が 0。npm run lint・npx tsc --noEmit・npm run test:unit(1606 files / 28764 tests)はすべて exit 0。GitHub Pages 上の確認はマージ後にオーケストレーターが行うため未実施。 - feat(website): LP の「What it gives you」の下にあった通信範囲の note を直後の新節「Runs on your machine」(
#trust)へ移し、3 ノードの inline SVG(.trust-diagram)と、機能ごとの通信を列挙する図の脚注で通信の範囲を示した (#2554): 文はdocs/design/public-messaging.md§14 の<!-- trust:en -->…<!-- /trust:en -->の逐語コピーで、語を変えずに 2 つに分けた — lede(<p class="trust-lede">)が本体の性質「CommandMate runs on your machine. It sends no telemetry, needs no account, and needs no external server to run.」、図の<figcaption class="trust-notes">が「What goes over the network depends on what you use:」と §14 の 5 経路(agent CLI の API ・ Web UI からの GitHub への更新確認 ・ Skills Catalog ・ Web Push の push サービス ・commandmate remoteの Tailscale / cloudflared、それぞれ「いつ」つき)の<ul>5 項目。Issue 本文の「任意機能(Web Push /remote)を有効にしたときだけ外部サービスを使う」は、更新確認が有効化なしで走るため #2549 で改めた §14 を正とし採らなかった。note は What it gives you から取り除いた(同じ文を 2 か所に置かない。#2553 の FAQ Q5 が同文を持つので「ページ全体で 1 回」はテストしていない)。図は Your machine(CommandMate「serves the web UI」と、破線の tmux 枠の中の Agent CLI)/ Browser or phone / The agent's API の 3 ノードと、接続を開く向きの矢印 2 本(web UI・API calls)だけで、機能ごとの通信は矢印にせず脚注に置いた。guard は hero と同じ(role="img"、aria-label 312 字、viewBox="0 0 400 250"+width="400" height="250"、全インク custom property、markup にfill=/stroke=/style=無し)。styles.cssは/* Trust (#2554) */…/* /Trust (#2554) */の 1 ブロック(901px 以上で図と脚注を 2 列、未満は 1 列)。テストはINLINE_DRAWINGSに'trust-diagram'を追加(#1812 の custom property 走査と #2551 の markup インク走査の対象に入る)し、describe('Issue #2554: Trust')に 10 件: What it gives you の直後に在り見出しが Runs on your machine ・ lede と脚注を連結すると §14 のtrust:enと一致 ・ 脚注の項目数が §14「機能ごとの通信(根拠)」表の行数(5)と一致 ・ カードの節にclass="note"も telemetry / over the network も無い ・website/**に "The only network traffic" と §14「書かない表現」の無条件の語(100% locally・no cloud relayほか)が無く、No external serverは " to run" つきでしか現れない ・INLINE_DRAWINGSに在る ・ inline ・ aria-label 40 字超 ・ viewBox + size ・ 3 ノードのラベル。変異注入(各回単独実行し、戻して 105 件緑を確認):.trust-diagram .arrowheadのfillを#59636eにすると「takes every ink in the drawing from a custom property」が赤 ・ §14 のtrust:en内のtelemetryをtelemetrYにすると「states §14 verbatim」が赤 ・.machine-frameにfill="#fff"で #2551 の markup 走査が赤 ・ "The only network traffic" を index.html に戻すと・裸の "No external server." を足すと走査が赤 ・ 脚注 1 項目削除で逐語と項目数の 2 件が赤 ・ カードの節に note を戻すと赤 ・ tmux ラベル変更で 3 ノードが赤。コントラスト(WCAG、ライト / ダーク):--fgon--bg15.80 / 16.02、--fg-mutedon--bg6.11 / 6.50(lede ・ 脚注 ・ 矢印ラベル)、--fgon--accent-subtle14.02 / 12.20(Your machine)、--fgon--surface15.80 / 14.65 と--fg-mutedon--surface6.11 / 5.94(ノード文字 ・ tmux)、--fgon--bg-subtle14.84 / 14.65 と--fg-mutedon--bg-subtle5.74 / 5.94(Agent CLI チップ ・ code)で、すべて 4.5:1 以上。表示確認はnode_modules/playwrightの headless Chromium でfile://を開き 1280×800 / 390×844 × light / dark の 4 通り:scrollWidth=clientWidth(1280 / 390)で横スクロール無し、図は 448×280 px(1280)/ 350×219 px(390、最小文字 11 user unit = 9.6 px)、SVG の全<text>の bbox が属する枠の内側(はみ出し 0 件)、fillの算出値が各テーマの token 値。npm run lint・npx tsc --noEmit・npm run test:unit(1606 files / 28765 tests)緑。 - feat(website): LP の nav を Docs ・ Tutorial ・ Changelog ・ GitHub にし(560px 以下は Docs と GitHub を残す)、ページ内アンカーを footer へ移して Releases ・ Discussions を足し、
<head>に Releases の Atom フィード、hero の prereq 行の下に静的な版行、website/llms.txtを置いた (#2552): nav のリンク先は Docs =https://github.com/Kewton/CommandMate/tree/main/docs/en、Tutorial =…/blob/main/docs/en/user-guide/tutorial.md、Changelog =…/releases、GitHub = リポジトリ。560px 以下で隠す規則は位置指定の.nav-links a:not(:last-child)(Docs を足すと GitHub 以外を全部隠す)から class 指定の.nav-links .nav-secondary(Tutorial ・ Changelog のみ)に替えた。既存の The loop / Quick start / With / Without は footer の「On this page」群へ移し、footer の「Project」群を GitHub ・ Docs ・ Releases ・ Discussions(https://github.com/Kewton/CommandMate/discussions)・ npm ・ MIT License にした(X はアカウント未決定のため置かない)。<head>に<link rel="alternate" type="application/atom+xml" href="https://github.com/Kewton/CommandMate/releases.atom" title="CommandMate releases" />。版行は API を呼ばない静的な 1 行<p class="release-line">v0.36.1 · released 2026-09-13 · 130+ releases</p>(Issue 本文の例 v0.36.0 の後に v0.36.1 が出たため package.json の0.36.1に合わせた。日付はgh release view v0.36.1の publishedAt2026-09-13T12:07:02Z=JST 同日で CHANGELOG の## [0.36.1] - 2026-09-13と一致、件数はgh api repos/Kewton/CommandMate/releases --paginate --jq '.[].tag_name' | wc -l= 137 を 10 の位で切り捨てた130+)。.claude/skills/release/SKILL.mdに Phase 2-2a「LP の版行」を足した: 日付を 2-2 で書いた CHANGELOG 見出しから awk で取り、上のgh apiの件数に作成予定の 1 本を足して 10 の位で切り捨て、node -eで<p class="release-line">…</p>がちょうど 1 つあることを確かめて置換する(版・日付・件数が形式外 = 見出し無し・gh失敗で floor 0 のときは書かずに exit 1)。2-4 のgit addにwebsite/index.htmlを加え、基本ファイル数を 3 → 4 に直した。ドライラン: 使い捨ての sparse clone(git clone --depth 1 --no-checkout+sparse-checkoutで index.html ・ CHANGELOG.md ・ package.json ・ SKILL.md のみ)で CHANGELOG に## [0.36.2] - 2026-09-14だけを足し(npm version ・ tag ・ push はしていない)、SKILL.md から抜き出した 2-2a の bash ブロックをNEXT_VERSION=0.36.2で zsh と bash の両方で実行 →date=2026-09-14 count=137 floor=130・RELEASE_LINE=0、git diff --statは CHANGELOG.md 2 行 + website/index.html の版行 1 行(v0.36.1 · released 2026-09-13→v0.36.2 · released 2026-09-14)のみ。見出しの無いNEXT_VERSION=0.36.3ではrefusing to write: version=0.36.3 date= floor=130・RELEASE_LINE=1で index.html は無変更。確認後に clone は削除した。website/llms.txtは H1# CommandMate — One agent leads. Gates decide what's done.、§1 の lede(blockquote)と事実行、Status: Beta とnpx commandmate@latestと prereq、§3 の 4 カード(- **タイトル**: 1 文)、Docs 群(docs/en ・ Tutorial ・ Setup guide ・ CLI operations guide)と Project 群(GitHub ・ Releases ・ Discussions ・ npm)で、文言は LP とdocs/design/public-messaging.mdからのコピー(public-messaging.md は無変更)。TEXT_FILEの.txtで禁止語走査と §11b 走査の対象に入り、禁止語 0。リンク確認(curl -sI -L -o /dev/null -w '%{http_code}'):https://github.com/Kewton/CommandMate・…/tree/main/docs/en・…/blob/main/docs/en/user-guide/tutorial.md・…/releases・…/discussions・…/releases.atom・…/blob/main/LICENSE・…/blob/main/docs/en/user-guide/cli-setup-guide.md・…/blob/main/docs/en/user-guide/cli-operations-guide.mdはすべて 200。footer の既存リンクhttps://www.npmjs.com/package/commandmateは curl だと 403(npmjs.com のボット遮断、GET + ブラウザ UA でも 403)だが、headless Chromium のpage.gotoでは 200(titlecommandmate - npm)、https://registry.npmjs.org/commandmateも 200。tests/unit/website/landing-page.test.tsに「Issue #2552」ブロック 16 件(79 → 95): nav の 4 リンクと順序 ・ 560px 以下の規則が class 指定で Docs と GitHub が残ること ・ footer にアンカー 3 つがありページ内の全href="#…"が実在 id に着地すること ・ footer の Discussions / Releases と X 無し ・ head の Atom フィード ・ 版行が package.json の version と一致し prereq と CTA の間にあること ・ 版行の日付が CHANGELOG の見出しと一致すること ・ 件数が 10 の倍数 ・ release スキルのnode -eスクリプトを一時ディレクトリの複製ページに実行して版行 1 行だけが変わること ・ floor 0 では exit 1 で書かないこと ・ 2-4 のgit add行に website/index.html ・ llms.txt が走査対象に入ること ・ llms.txt の H1 / lede / 事実行 ・ 4 カードが §3 と逐語一致 ・ docs / tutorial / GitHub へのリンク ・ Node の major が engines と一致。変異注入(各回ファイルを復元): 版を v0.36.0 ・ 日付を 2026-09-12 ・ 件数を 137+ ・ CSS を:not(:last-child)に戻す ・ Tutorial のnav-secondaryを外す ・ footer にhttps://x.com/fooの X ・#loopを#loops・ SKILL.md の置換正規表現のクラス名 ・ floor の検査を外す ・git addから website/index.html を外す ・ llms.txt のカード文 1 字 ・ llms.txt のNode.js v22+を v20+ ・ llms.txt にOrcaの 13 通りすべてで対応するテストが赤。表示確認はnode_modules/playwrightの headless Chromium でfile://を開き(サーバは起動していない)、1280×800 ・ 560×800 ・ 390×844 × ライト / ダークの 6 通りで hero ・ hero コピー ・ footer を撮影(dev-reports/issue/2552/): 6 通りともscrollWidth=innerWidth、ヘッダ高 54px で表示中のリンクは全て同じ行(top 15px)、1280px は 4 リンク、560px と 390px は Docs と GitHub のみ。320 ・ 360 ・ 561 ・ 600 ・ 768 ・ 900 ・ 901px でも 1 行で横スクロール無し。npm run lint・npx tsc --noEmit・npm run test:unit(1606 files / 28755 tests)はすべて exit 0。GitHub の About(gh repo edit --homepage)はマージ後にオーケストレーターが行うため未実施。
Changed
- refactor(website): LP の The loop の 4 拍を 1 枠の帯(901px 以上は 4 列・未満は縦並び)にして契約・send・verify のコード片を
<details class="beat-fold">に畳み、See it running の残り 4 本を 2×2 に、Catalog 14 ID を §3d の見出しを summary にした<details class="catalog-fold">に、closing と Philosophy を 1 節にした (#2555): 文言は 1 語も変えず、節も消していない(Epic #2548 で生じた重複を減らす追加圧縮)。beat の summary はページに既にある語だけ(fix-shout.yaml・commandmate send・ FAQ が書くcommandmate wait --verify)で、畳んだ snippet 自体は無変更。901px 以上の The loop は見出しと lede の横にループ図(22rem、スマホと同じ幅)を置き、4 本のデモはキャプションを動画の横に置いた(900px 以下はキャプションが下)。収録 run ・ Measured 表 ・as observed・ §3e-4 ・ §3c の段落は据え置きで、デモは<details>に入れていないので #2556 の遅延再生はそのまま(headless Chromium で初回ロードの mp4 リクエスト 0、グリッドまでスクロールすると 4 本とも再生、戻ると停止を確認)。closing は<section class="section philosophy" id="philosophy">の中の<div class="closing">になり、#philosophyと定義文の逐語照合は変わらない。畳んだ 4 つの<summary>は Tab で到達し Enter で開き Space で閉じること、1280 / 390 を含む 7 幅 × ライト / ダークで開閉どちらでも横スクロールが出ないことを確認した。CSS は/* Compact 2 (#2555) */の 1 ブロックで transition / animation を宣言していない。docHeight は 1280×900 で 12,306 → 10,469px(目標 ≤ 10,500 を達成)、390×844 で 17,812 → 15,942px(目標 ≤ 15,000 には 942px 届かず、残りは 4 点の範囲外か据え置き指定の内容。内訳はdev-reports/issue/2555-compact2/report.md)。テストはdescribe('Issue #2555: compact (2)')に 6 件を足し、既存テストは #2550 の「Catalog の見出しを<p class="card-more">から読む」1 か所だけを<summary id="catalog-h">から読むよう変えた(見出しが<details>の summary になり、<summary>の中に<p>は置けないため。§3d と照合する文字列は同じ)。 - refactor(website): LP の Quick start の Track B をネイティブの
<details class="track-fold">(summary は見出しInstall it for daily use)に畳み、「Pair your phone」節を lede ・commandmate remoteのコマンド ・ CLI operations guide へのリンク行だけにし、ギャラリーを 7 枚から 4 枚にした (#2555): 文言は 1 語も変えていない(削ったのは remote の 4 カード ・ 有効期限の note ・ ギャラリーの 3 figure だけ)。Track B の 3 コマンドと copy ボタンは<details>の中に残し、<h3 id="track-daily-h">を<summary>に入れてカードのaria-labelledbyと見出しの並びを保った。Playwright の headless Chromium で閉じた状態から開いて 3 つの copy ボタンを押し、クリップボードにnpm install -g commandmate・commandmate init・commandmate start --daemonが入ること、<summary>が Enter / Space で開閉することを確認した(main.jsは無変更)。remote の 4 カード(providers / yes / code / door)と note の内容はdocs/en/user-guide/cli-operations-guide.mdの### commandmate remote節(Provider status ・ A public tunnel needs explicit approval ・ Pairing code ・ Expiry closes the outward door only ・ remote stop does not guess と冒頭のCM_BIND/ Auto-Yes の注記)に在ることを確かめ、その見出しと語をテストで固定した。ギャラリーはscreenshot-desktop.webp(og:image、据え置き)・screenshot-worktree-desktop-chat.webp・screenshot-mobile.webp・screenshot-worktree-mobile-chat.webpの 4 枚で、901px 以上は 6 トラックの 1 行(横長 2 トラック ・ 縦長 1 トラック)、900px 以下は横長を 1 行ずつ ・ 縦長 2 枚を横並び(幅 40rem 上限)にした。外した 3 枚は参照をすべて消したがファイルは削除していない —tests/unit/skills/demo-video/stills.test.tsがstills.tsの撮る 5 枚すべての webp の存在を要求しており、そのテストとstills.tsは本 Issue の scope 外のため(website/assets/media/README.mdにその理由を書き、ページが参照しない画像はこの 3 枚以外を許さないテストを足した)。CSS は/* Compact (#2555) */の 1 ブロックに置き、ギャラリーの列指定をそこへ移し、使われなくなった.remote-cardsを消した。docHeight は 1280×900 で 13,865 → 12,306px、390×844 で 22,632 → 17,812px(ライト / ダーク同値、横スクロールなし)で、目標の 5,400 / 8,440 には届いていない(節ごとの内訳はdev-reports/issue/2555/report.md)。テストはtests/unit/website/landing-page.test.tsのdescribe('Issue #2555: compact')に 9 件を足し、既存テストの期待値は変えていない。 - feat(website): LP の hero 右カラムを、ループ図からゲート行つきセッション一覧の inline SVG(
.hero-mock)に差し替え、ループ図(.loop-diagram)を「The loop」節の冒頭(lede の直下、4 拍の前)へ移した (#2551): "gate" を「判断待ちの質問」の意味で使う製品があり語が衝突するため、ファーストビューで gate=宣言したコマンドの exit code を図で定義する。モックはセッション 4 行(wt-retryClaude Code working ・wt-pickCodex done ・wt-authAntigravity の amber 行 "needs you" ・wt-docsCommand Code working)と、その下の端末枠$ commandmate wait wt-pick --verify→GATE work-evidence PASS/GATE unit PASS (exit=0)/RESULT passed/$ echo $?→0(書式はsrc/cli/utils/verify-runner.tsのGATE <id> <LABEL> (detail)/RESULT <status>、0の注記は §3 カード 2 の "the exit code is the verdict" の抜粋)。amber 用に--attention/--attention-subtleをライト(#8a5a00/#fff3d6)とダーク(#e3b341/#33270c)で追加し、図の全インクは custom property(literal color 0)。og:image は据え置き(100KB 予算に不接触)、hero に<video>無し、docs/design/public-messaging.mdは無変更。コントラスト(WCAG 比、ライト / ダーク):--fgon--surface15.80 / 14.65、--fg-mutedon--surface6.11 / 5.94、--fgon--accent-subtle14.02 / 12.20、--fg-mutedon--accent-subtle5.43 / 4.95、端末枠--bg-subtle上の--fg14.84 / 14.65 と--fg-muted5.74 / 5.94、amber 行--attention-subtle上の--fg14.33 / 12.37 と--fg-muted5.54 / 5.02、"needs you" ラベル(--attentionon--surface)5.93 / 8.90、amber のドット(--attentionon--attention-subtle)5.37 / 7.51 で、すべて 4.5:1 以上。tests/unit/website/landing-page.test.tsは「Issue #1812: the hero diagram」の custom property 走査を付け替えではなくINLINE_DRAWINGS = ['hero-mock', 'loop-diagram']の両方へ広げ(クラスごとに塗りの宣言が 5 件以上あることも要求。#2554 の.trust-diagramは配列に 1 つ足すだけ)、4 テストのまま緑。新設の「Issue #2551」ブロックに 4 件(75 → 79): hero にモックがありループ図は The loop にだけ在ること、The loop の 4 拍より前にループ図がありrole="img"・ 40 字超のaria-label・viewBox+width/heightを保つこと、pill が 4 つで "needs you" が amber 行に 1 つ・端末行が上記 6 行と一致すること、両 SVG のマークアップにfill=/stroke=/color=/stop-color=/style=属性を書かないこと(CSS 走査から見えないため)。変異注入の結果(各回の復元後にバイト一致を確認):.hero-mock .termのfillを#1f2328→takes every ink in the drawing from a custom propertyが赤(".hero-mock .term { fill: #1f2328 }")、.loop-diagram .edgeのstrokeを#59636e→ 同テストが赤(".loop-diagram .edge { stroke: #59636e }")、対照として同じ.hero-mockの変異を HEAD(#2550)時点のテストファイルで走らせると 75 件すべて緑(走査の拡張が必要だったことの確認)、hero の端末行にfill="#1f2328"属性 →writes no ink into the markup of either drawingが赤、ループ図を hero へ戻す →draws the session mock in the hero…とopens The loop on the loop drawing…の 2 件が赤。表示確認はnode_modules/playwrightの headless Chromium でfile://を開き(サーバは起動していない)、1280×800 と 390×844 × ライト / ダーク(colorScheme)の 4 通りで実測した: 4 通りともdocument.documentElement.scrollWidth=innerWidth(1280 / 390、横スクロール無し)、1280px では.hero-mockが 448×460px(hero 右カラム 530.6px 内、max-width: 28rem)、ループ図が 480×360px(.loop-figureのmax-width: 30remで中央寄せ)、390px ではどちらも幅 350px = 親の内容幅 350px(モック 350×359.7px、ループ図 350×262.5px)。両 SVG とも全<text>の bbox が viewBox 内(はみ出し 0)、端末行の右端は端末枠の内側 90.3 単位、pill ラベルは pill の内側 12.5 単位以上に収まり、ライト / ダークで寸法は同一、スクリーンショットで配色の崩れが無いことも確認した。npm run lint・npx tsc --noEmit・npm run test:unit(1606 files / 28739 tests)はすべて exit 0。 - feat(website): LP の「See it running」の収録 run 直下に Measured 表(
docs/design/public-messaging.md§3b)を置き、See it running と The loop の間に新節「One agent leads」(§3e の lead の run ・ 契約 YAML ・ Review by another agent)を足し、The loop を worker 1 体の 1 ターン(lede は §3e-6)に圧縮した (#2550): 文言はすべて public-messaging からコピーし README からは写していない(public-messaging.md 自体は無変更)。Measured 表は §3b の en 表を全セル逐語で.table-scrollに入れ、表の直下にas observed、続けて §3e-4(lead の実測の範囲)を置いた。新節#leadは lede が §3e-2(「Nothing mutates without an explicit approve, and a failed gate stops the run.」を含む)、plan → dispatch → merge → uat の 4 ステップと直下の note が §3e-1、.commandmate/tasks/issue-21.yamlの.snippetと組み込みゲートの注記が §3e-3、「Review by another agent」が §3e-5 の段落を丸ごと(ランナーが cross-model review をやるとは書かない 3 文目まで)。「What it gives you」はカード 1 の直下に §3c(Supported agents)、カード 4 の下に §3d の Catalog ID 14 件のチップを足し、2 枚だけが縦に伸びないよう 4 列を 2 列にした。The loop は 4 拍(要件 → 契約 → 走る → 判定)を維持したまま各拍を 1 文 + 1 つのコード片に削り、契約の全体は上の節で見せるのでverify.yamlの片を外した(section の高さ 1280px 幅 1219 → 1021px、390px 幅 2026 → 1733px)。nav は変更しない(拡張は #2552)。tests/unit/website/landing-page.test.tsに 11 件(64 → 75)を追加し、Measured 表の thead / tbody 全セル ・as observedが表の直下にあること ・ §3e-1〜6 ・ §3c ・ §3d の逐語一致と並び順を public-messaging から読んで照合する。変異注入の結果(10 件すべて赤、各回の復元後にバイト一致を確認): §3b の8 min 39 s→8 min 38 sと4 × Command Codeの×→x→copies the Measured table from §3b cell for cellが赤、§3b 表直下のas observed→as observe→puts "as observed" directly under the table, then §3e-4が赤、LP 側の47/47→46/47→ 表の照合が赤、§3e-5 の最終文を削る →states §3e-5 wholeが赤、§3d の ID 2 つを入れ替え → チップの照合が赤、LP の YAML のインデントを 1 桁ずらす →shows the §3e-3 contract byte for byteが赤、§3e-1 ・ §3e-6 ・ §3c の 1 語 → それぞれの照合が赤。表示確認はnode_modules/playwrightの headless Chromium でfile://を開き(サーバは起動していない)、1280×800 と 390×844 × ライト / ダーク(colorScheme)の 4 通りで実測した: 4 通りともdocument.documentElement.scrollWidth=innerWidth(ページの横スクロール無し)、1280px では Measured の.table-scrollと YAML の.snippetがともに幅 1040px = 親の内容幅 1040px でscrollWidth=clientWidth(内部スクロールも無し)、390px ではどちらも幅 350px = 親の内容幅 350px に収まり、はみ出す分は Measured 表が.table-scrollの中(scrollWidth672 >clientWidth348)、YAML が.snippet(overflow-x: auto)の中(720 > 348)だけで横スクロールする。ライト / ダークで寸法は同一、スクリーンショットで配色の崩れが無いことも確認した。npm run lint・npx tsc --noEmit・npm run test:unit(1606 files / 28735 tests)はすべて exit 0。 - docs(website): 公開面の単一ソース
docs/design/public-messaging.mdに LP の新節が写す文言(§3b Measured ・ §3c Supported agents ・ §3d Catalog 一覧 ・ §3e One agent leads ・ §13 FAQ 8 問 ・ §14 Trust)を en / ja で追記し、README en / ja と LP の通信範囲の過大表現を §14 の文へ置き換え、禁止語にOrca/Herdr/Lanesを加えた (#2549): §3b ・ §3c ・ §3e-2〜5(本文 ・ 契約 YAMLissue-21.yamlと組み込みゲートの注記 ・ lead の実測の範囲 ・ Review by another agent)は README の該当節から逐語で収録し、README en / ja に文字列として含まれることを照合スクリプトで確認した。§3d はgh api repos/Kewton/commandmate-skills/contents/skillsでskills/直下 14 件を確認して並べ、§3e-1(plan → dispatch → merge → uat の 4 ステップ、根拠はcmate-orchestrateの SKILL.md)と §3e-6(The loop を worker 1 体の 1 ターンと位置づける lede)は LP 用に新しく書いた。§13 はfaq:en/faq:ja、§14 はtrust:enの HTML コメントマーカーで囲み(#2553 / #2554 の逐語照合用)、Q5 の答は §14 の文そのもの、Q8 は §4b の 4 行目を含む。README.md:208 ・docs/ja/README.md:207 ・website/index.html:379 の「Runs 100% locally. No external server, no cloud relay, no account required. The only network traffic is the agent CLI's own API calls.」を撤回し、§14 の「本体はテレメトリ無し ・ アカウント不要 ・ 動かすのに外部サーバ不要」と機能ごとの通信の列挙に置き換えた。列挙は Issue の 3 経路(agent CLI の API ・ Web Push の push サービス ・commandmate remoteの Tailscale / cloudflared)に、実装を読んで見つかった 2 経路(Web UI の更新確認 = GitHub Releases APIsrc/lib/version-checker.ts、Skills Catalog の取得 = GitHubsrc/lib/skills/catalog-client.ts)を足した。更新確認は利用者が有効化しなくても走るので、「任意機能を有効にしたときだけ」とは書かず各経路に「いつ」を添え、根拠表と「書かない表現」表を §14 に置いた。§9 の表 ・BANNED_TERMS・LP_BANNED_TERMSに 3 語を足し、landing-page.test.tsに「理由が 競合製品名 の行(同上は直前の行を継承)がすべてLP_BANNED_TERMSに在る」検査を追加した。変異注入の結果: 表だけに 3 語 →publishes the banned-term list this test enforcesが赤、BANNED_TERMSだけに 3 語 → 同じテストが赤、LP_BANNED_TERMSから 3 語(またはLanesだけ)を抜く → 新検査だけが赤(既存の traceability 検査は緑のまま)、website/index.htmlにOrca→ships none of the retired wording anywhere under website/が赤、README.mdにHerdr→README.md uses none of the banned termsが赤(いずれも復元後に sha 一致を確認)。README en / ja ・docs/concept.md・docs/en/concept.md・website/**の 3 語は 0 件。§12 に Epic #2548 の子 Issue #2549〜#2557 を追加した。
Fixed
- fix(website): LP のデモ動画 5 本から
autoplay属性を外してdata-autoplayに置き換え、main.jsの IntersectionObserver(threshold 0.25)で画面に入った動画だけをplay()するようにし、初回ロードで 5 本(合計 3.0 MB)を全部ダウンロードしていた事象を止めた (#2556):preload="none"は付いていたが、autoplayはpreloadより優先される(MDN: "The autoplay attribute has precedence over preload")ため効いていなかった。Playwright で静的サーバ(python3 -m http.server)からwebsite/を配信しpage.on('request')で数えた、スクロール位置 0・ロード後 3 秒時点の.mp4リクエスト数は Chromium の 1280×900 / 390×844 とも変更前 5 → 変更後 0(両 viewport とも初期表示で viewport に入る<video>は 0 本なので許容分なし。WebKit でも 0)。動画を順にスクロールして中央に置くと 5 本ともvideo.paused === falseになり、150px 刻みでページ全体をスクロールして「25% 以上見えていて止まっている/20% 以下で再生中」の食い違いは Chromium ・ WebKit の両 viewport で 0 件、先頭に戻すと全本停止。main.jsは 25% 以上見えたらplay()、下回ったら再生中のものだけpause()(observe 直後の初回通知で未ロードの動画にpause()を呼んでリソース選択を走らせないため)、IntersectionObserver が無いブラウザでは従来どおり読み込み時に全本play()(delete window.IntersectionObserverを仕込んだ Chromium で 3 秒時点 5 本・全本再生を確認)、play()の Promise の reject(自動再生ブロック)は握りつぶしてコンソールに出さない。prefers-reduced-motion: reduceでは従来どおり自動再生せず、data-autoplayを外してcontrolsを出しloopを切る(Chromium のreducedMotion: 'reduce'でスクロール後もリクエスト 0 ・再生 0)。muted/playsinline/loop/preload="none"/posterは維持。tests/unit/website/landing-page.test.tsの既存 3 テスト(five demos in page order ・ muted and playsinline ・ reduced motion)をdata-autoplayを見る形に更新し、describe('Issue #2556: lazy demo playback')に jsdom でindex.htmlとmain.jsを実際に動かすテスト 7 件(IntersectionObserver ありでは読み込み時にplay()しない・threshold 0.25 で 5 本を observe ・ 0.1 では再生せず 0.25 で再生し 0.2 で停止・非対応時は即時 5 本再生・play()時点でmutedとplaysinlineが揃っている・reject を unhandled rejection にもコンソール出力にもしない・reduced motion では observer の有無にかかわらず再生せずcontrols)を追加し、catch削除・threshold 0・isIntersectingのみでの再生・フォールバック削除などの 9 通りの変異がいずれかのテストで赤になることを確認した。iOS Safari は実機での確認は未実施(muted+playsinline+play()の条件をテストで固定したのみ)。 - fix(hooks):
useSplitMessages/useTerminalPanePollingがアンマウント後に返った fetch 応答で state を更新しないようにし、CI の Unit Tests が全テスト PASS のまま Unhandled Error で exit 1 になる事象を止めた (#2559): 両フックの fetch は「新しいリクエストに追い越された」「CLI / instance が変わった」応答しか捨てず、ポーリング effect のクリーンアップも飛行中の fetch は止めないため、アンマウント後に settle した応答(成功・失敗とも)がsetMessages/setIsLoading(useTerminalPanePollingはsetTerminal/setPrompt/setAgentSession、失敗時はconsole.error)に届いていた。React 19 は更新の優先度を fiber の生死を見る前にwindow.eventから決めるため、jsdom 破棄後にこれが起きるとwindow is not definedが投げられていた。effect 本体で true・クリーンアップで false にするmountedRefを追加し(StrictMode の unmount → remount でも true に戻る)、既存の stale 判定と一本化したisStale()で成功・失敗の両出口から捨てる。fetch を手で解決する Promise にし、unmount()→vi.stubGlobal('window', undefined)→ settle の順で確かめる決定的な回帰テスト(useSplitMessages-unmount-2559/useTerminalPanePolling-unmount-2559、各 3 ケース)を追加。