octopus-ui-ux-design について
Codex CLI向けのUI/UXデザインスキルで、デザインの方向性やデザインシステムの策定を支援します。対話による要件確認とBM25検索を行い、批判的なレビューと修正を経て提案します。
主な機能
- 01対話形式でのデザイン要件確認
- 02BM25に基づくデザイン調査
- 03条件を満たす場合の並列案生成
- 04批判的レビューと修正
- 05デザイントークン、コンポーネント、レイアウト
活用シーン
- 01製品概要からビジュアル方針を策定
- 02デザインシステムの成果物を作成
- 03実装前にデザイン案をレビュー
MCP 対応
Figma URLが指定された場合、Figma MCPツールでデザインコンテキストやスクリーンショットを取得する手順が記載されています。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nyldn/ claude-octopus --skill octopus-ui-ux-designインストール後、Claude Code で/octopus-ui-ux-designを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yaml
詳細
ホスト:Codex CLI — このスキルは Claude Code 向けに設計され、Codex 用に調整されています。 相互参照するコマンドでは、
/octo:*スラッシュコマンドではなく、Codex にインストールされたスキル名を使用します。 アクティブな Codex のシェルとサブエージェントツールを使用してください。現在のセッションで利用可能になっていないプロバイダー、モデル、ホストのサブエージェントが利用可能であると主張しないでください。 ホストツールに相当するものについては、skills/blocks/codex-host-adapter.mdを参照してください。
実行契約(必須 — 省略不可)
**重要:デザインに関する提案を行う前に、ネイティブのシェルコマンドツールを使用して BM25 検索エンジン(search.py)を必ず呼び出してください。自身のデザイン知識のみに頼ってはいけません。検索エンジンは、厳選されたデータに基づくデザイン情報を提供します。search.py を少なくとも 3 回呼び出さずにデザインシステムを作成した場合、この契約に違反したことになります。**このスキルは強制実行モードを使用します。以下の手順を必ず順番どおりに実行してください。
STEP 1:質問による確認(必須)
ほかの操作を行う前に、必ず AskUserQuestion を呼び出してください。
AskUserQuestion({
questions: [
{
question: "What type of product are you designing for?",
header: "Product Type",
multiSelect: false,
options: [
{label: "SaaS/Dashboard", description: "Analytics, admin panels, B2B tools"},
{label: "E-commerce", description: "Shopping, marketplace, product pages"},
{label: "Landing page", description: "Marketing, conversion, product launch"},
{label: "Mobile app", description: "iOS/Android native or responsive"}
]
},
{
question: "What tech stack are you using?",
header: "Stack",
multiSelect: false,
options: [
{label: "React + Tailwind (Recommended)", description: "React/Next.js with Tailwind CSS"},
{label: "React + shadcn/ui", description: "React with shadcn component library"},
{label: "HTML + Tailwind", description: "Static or server-rendered HTML"},
{label: "Vue/Nuxt", description: "Vue.js or Nuxt framework"}
]
},
{
question: "What design deliverables do you need?",
header: "Deliverables",
multiSelect: true,
options: [
{label: "Design tokens", description: "Colors, spacing, typography as CSS/Tailwind config"},
{label: "Component specs", description: "Component anatomy, states, props"},
{label: "Page layouts", description: "Wireframe-level layout specifications"},
{label: "Style guide", description: "Visual style direction with rationale"}
]
},
{
question: "How adventurous should the design be?",
header: "Dials",
multiSelect: false,
options: [
{label: "Conservative (v3 m2 d4)", description: "Familiar patterns, minimal motion — enterprise, gov, finance"},
{label: "Balanced (v5 m4 d5)", description: "Contemporary but safe — most SaaS and product work"},
{label: "Expressive (v7 m6 d5)", description: "Distinctive direction, noticeable motion — marketing, launch pages"},
{label: "Maximal (v9 m8 d6)", description: "Take real aesthetic risks — portfolios, creative brands"}
]
}
]
})
ダイヤルの回答は --variance/--motion/--density の値(上記の v/m/d)に対応し、すべての search.py 呼び出しに渡して、デザインの方向性にも明記します。ユーザーの概要ですでにビジュアルスタイル(たとえば「ブルータリスト」「遊び心のある」「コーポレート」)が指定されている場合は、ダイヤルに関する質問を省略し、そのスタイルから 3 つの値を推定します。推定した値を記録してください。明示的なユーザーの回答もある場合は、推定値より明示的な回答を優先します。それ以外の場合は、通常どおりダイヤルに関する質問をしてください。
3 つのダイヤル値はすべて、1 から 10 までの整数でなければなりません。スタイル名から値を推定する場合は、以下のプリセットを使用してください。類義語には最も近い行を選び、選択した行と値を記録してください。
| スタイルの手がかり | 変化度 | モーション | 密度 |
|---|---|---|---|
| コーポレート/エンタープライズ/保守的 | 3 | 2 | 4 |
| クリーン/モダン/バランス重視 | 5 | 4 | 5 |
| 遊び心のある/表現豊か/レトロ | 7 | 6 | 5 |
| ブルータリスト/マキシマル/実験的 | 9 | 8 | 6 |
各 search.py 呼び出しの前に、値が範囲内であることを検証してください。明示値または推定値が不足している場合、数値でない場合、あるいは 1~10 の範囲外の場合は、値を丸めずに処理を停止し、有効な値を取得してください。
STEP 2:バナーの表示
必須:バナーを表示する前に、ネイティブのシェルコマンドツールを使用して、必ずこのプロバイダーチェックを実行してください。省略したり、利用可能だと決めつけたりしないでください。
bash "${HOME}/.claude-octopus/plugin/scripts/helpers/check-providers.sh"
以下の実際の結果を使用してください。禁止事項:すべてのプロバイダーを列挙せず、「🔵 Claude:利用可能 ✓」だけを表示すること。
🐙 **CLAUDE OCTOPUS ACTIVATED** - UI/UX Design Mode
🎨 Design: [Brief description from user prompt]
Pipeline:
🔍 Phase 1: Design Research (BM25 search + context detection)
🎯 Phase 2: Design Direction (synthesis + style selection)
🐙 Phase 2b: Design Critique (adversarial review before committing)
🛠️ Phase 3: Design System (tokens, components, layouts)
✅ Phase 4: Validation (accessibility, handoff specs)
Providers:
🔴 Codex CLI: [Available ✓ / Not installed ✗] — Implementation critique
🟡 Antigravity CLI: [Available ✓ / Not installed ✗] — Ecosystem critique
🧭 Antigravity CLI: [Available ✓ / Not installed ✗] — Additional external-model challenge
🔵 Claude (Sonnet): Available ✓ — Design + independent critique
Tools:
🔍 BM25 Design Intelligence: [checking...]
🎨 Figma MCP: [Available / Not configured]
🧩 shadcn MCP: [Available / Not configured]
STEP 3:デザイン情報の確認
SEARCH_PY="${HOME}/.claude-octopus/plugin/vendors/ui-ux-pro-max-skill/src/ui-ux-pro-max/scripts/search.py"
if [ -f "$SEARCH_PY" ]; then
python3 -c "import csv, re, math" 2>/dev/null && echo "READY" || echo "MISSING_PYTHON"
else
echo "MISSING_SEARCH_PY"
fi
MISSING_SEARCH_PY の場合:ベンダー提供のデザイン情報ファイルがありません。プラグインを再インストールまたは更新するようユーザーに伝えてください(vendors/ui-ux-pro-max-skill/ ディレクトリはプレーンファイルとして同梱されています)。
MISSING_PYTHON の場合:デザイン情報を利用するには python3 が必要であることをユーザーに伝えてください。
いずれの場合も、修正方法を伝えた後、このワークフローを終了します。事前確認の結果が READY の場合に限り、STEP 4 に進んでください。
STEP 4:フェーズ 1 — 調査(デザインリサーチ)
以下の検索を少なくとも 3 回実行してください。これは必須です。
SEARCH_PY="${HOME}/.claude-octopus/plugin/vendors/ui-ux-pro-max-skill/src/ui-ux-pro-max/scripts/search.py"
# 1. Product type search — what design patterns fit this product?
python3 "$SEARCH_PY" "<user's product description>" --domain product
# 2. Style search — what visual styles match?
python3 "$SEARCH_PY" "<user's aesthetic or product type>" --domain style
# 3. Color palette search — data-driven palette selection
python3 "$SEARCH_PY" "<user's product type or mood>" --domain color
# 4. Typography search — font pairings
python3 "$SEARCH_PY" "<user's product type>" --domain typography
# 5. UX guidelines search — relevant best practices
python3 "$SEARCH_PY" "<key user flow>" --domain ux
# 6. Stack-specific search (if user specified a stack)
python3 "$SEARCH_PY" "<user's requirements>" --stack <stack>
# 7. Full design-system draft with the dials from Step 1 (v2.11.0+)
python3 "$SEARCH_PY" "<user's product description>" --design-system \
--variance <v> --motion <m> --density <d>
ユーザーが Figma URL を提供した場合は、デザインコンテキストも取得してください:
- Figma MCP の
get_design_contextを使用して既存のデザインを取得します - 視覚的な参考資料として
get_screenshotを使用します
フェーズ 2 に進む前に、検索結果をすべて収集してください。
ステップ 4b:デザインのショットガンモード(利用可能なプロバイダーが3つ以上の場合に自動で有効化)
ステップ 2 のプロバイダーチェックで利用可能なプロバイダーが3つ以上検出された場合(常に利用可能な Claude を含む)、このステップは自動的に実行されます。 利用可能なプロバイダーが3つ未満の場合は、ステップ 5 に進み、標準的な単一方向モードを使用します。
同じデザイン概要を複数のプロバイダーに並列で送信します。各プロバイダーは、ほかのプロバイダーの成果物を見ずに、独立したデザインの方向性を生成します。
ホストのサブエージェントツールで background execution: true を使用して、3つ以上のバリアントエージェントを並列で起動します。
各エージェントに渡す内容:
Design a visual direction for: [user's product description]
Product type: [from Step 1]
Stack: [from Step 1]
Search context: [key findings from Step 4 BM25 searches]
Produce:
1. A style name (2-3 words, e.g., "Warm Minimalism", "Bold Industrial", "Cobalt Editorial")
2. Primary color palette (3-5 colors with hex values)
3. Font pairing (heading + body)
4. Layout philosophy (e.g., "generous whitespace with card-based content")
5. One paragraph describing the overall feel
Be distinctive — take a clear position rather than playing it safe.
Hard constraints (see skills/blocks/design-taste.md): do NOT produce any of the three
AI-slop looks (cream+serif+terracotta, near-black+acid accent, purple-violet gradients),
and do not default to Inter, Roboto, Space Grotesk, Fraunces, or Instrument Serif
without a brief-tied reason.
多様性を最大限に高めるため、異なるプロバイダーに送信します。
- 🔴 Codex:実装重視の方向性(素早く構築でき、拡張性が高いもの)
- 🧭 Antigravity:トレンドを意識した方向性(現在のデザインエコシステムに合うもの)
- 🔵 Claude:ユーザー中心の方向性(オーディエンスに最も役立つもの)
- 🟤 OpenCode / 🟢 Copilot / 🟣 Qwen:利用可能な場合は追加のバリアント
すべてのバリアントが返されたら、返された各結果全体を対応するプロバイダーに紐付けます。 プロバイダーを VARIANT_A_PROVIDER、VARIANT_B_PROVIDER、VARIANT_C_PROVIDER として記録し、対応する完全な出力を VARIANT_A_RESULT、VARIANT_B_RESULT、VARIANT_C_RESULT として記録します。各結果には、返されたスタイル名、パレット、フォント、レイアウトの考え方、雰囲気を含める必要があります。フィールドが欠けている場合は、そのエージェントに結果を補完するよう依頼してください。例の内容を創作したり、代わりに使用したりしないでください。実際に返された値を使って比較ボードを提示します。
🎨 **Design Shotgun — 3 Variants**
━━━ Variant A (${VARIANT_A_PROVIDER}) ━━━
${VARIANT_A_RESULT}
━━━ Variant B (${VARIANT_B_PROVIDER}) ━━━
${VARIANT_B_RESULT}
━━━ Variant C (${VARIANT_C_PROVIDER}) ━━━
${VARIANT_C_RESULT}
次に、ユーザーに選択してもらいます。
AskUserQuestion({
questions: [{
question: "Which design direction do you prefer?",
header: "Pick",
multiSelect: false,
options: [
{label: "Variant A", description: "[style name] — [one-line feel]"},
{label: "Variant B", description: "[style name] — [one-line feel]"},
{label: "Variant C", description: "[style name] — [one-line feel]"},
{label: "Mix & match", description: "Take elements from multiple variants"}
]
}]
})
選択後、選ばれたバリアントをデザインの方向性としてステップ 5 に進みます。 「Mix & match」が選ばれた場合は、進む前に組み合わせる要素を尋ねます。
ステップ 5:フェーズ 2 — 定義(デザインの方向性)
検索結果(およびショットガンモードの場合は選択したバリアント)を統合し、デザインの方向性を示すドキュメントを作成します。
- スタイルの推奨 — 製品に最適なビジュアルスタイル(検索結果を引用)
- カラーパレット — HEX 値とコントラスト比を含む選定済みパレット
- タイポグラフィ — Google Fonts のインポートを含む、見出しと本文のフォントの組み合わせ
- レイアウトのアプローチ — グリッドシステム、間隔の尺度、レスポンシブ対応方針
- デザイン原則 — UX の検索結果から導き出した、指針となる原則を3~5つ
- デザインテイストへの準拠 — この方向性が
skills/blocks/design-taste.mdに準拠していることを示す一文(禁止された3つの見た目のいずれでもないこと、正当な理由なく禁止対象のデフォルトフォントを使わないこと、大胆さを一箇所に集中させていること)
出力:次のステップで参照できるよう、デザインの方向性を構成されたセクションとして記述します。
ステップ 5b:デザイン批評 — 3者による対立的レビュー(必須)
このステップはデフォルトで実行されます。 デザインの方向性を決定する前に、最大3つの独立した視点から対立的な批評を受け、それに耐えられることを確認する必要があります。これにより、アクセシビリティ上の問題、実用性に欠ける選択、BM25 の盲点がトークンやコンポーネントに組み込まれる前に見つかります。
批評プロンプト(すべての参加者に送信):
Review this proposed design direction and find problems. Be adversarial — your job is to catch flaws, not validate choices.
[The full design direction from Step 5]
Critique dimensions:
1. ACCESSIBILITY — Do the proposed colors meet WCAG AA contrast ratios (4.5:1 text, 3:1 large text)? Are the font sizes readable at the proposed scale? Are touch targets viable?
2. PRACTICALITY — Does this typography actually render well on the stated tech stack? Are the fonts available and performant (file size, loading)? Does the spacing scale work with the layout system?
3. FIT — Does the visual style actually match the product type and audience? Would a user of [product type] feel comfortable with this aesthetic?
4. GAPS — What did the research miss? Are there common UX patterns for this product type that aren't addressed? Are there competitive norms being ignored?
5. SLOP — Run the checklist in skills/blocks/design-taste.md. Is this one of the three AI-slop looks (cream+serif+terracotta, near-black+acid, purple gradients)? Banned default fonts without a stated reason? Would another model given the same brief land on the same palette and fonts? Two or more checklist misses fail the direction.
For each issue found, state: what's wrong, why it matters, and what to do instead.
3人の参加者が並行して実行します:
# Check provider availability
providers=()
command -v codex >/dev/null 2>&1 && providers+=(codex)
command -v agy >/dev/null 2>&1 && providers+=(agy)
for provider in "${providers[@]}"; do
safe_provider=$(printf '%s' "$provider" | tr -c '[:alnum:]_-' '_')
"${HOME}/.claude-octopus/plugin/scripts/orchestrate.sh" spawn "$provider" \
"<critique prompt>" > "/tmp/design-critique-${safe_provider}.md" &
done
wait
🔵 Claude(Sonnet)— 独立したデザイン批評。 あなた自身の対立的な批評も必ず作成してください。外部プロバイダーの意見を要約するだけではいけません。デザインの方向性を自分が作成していないかのように捉え、5つの観点すべてについて積極的に問題を探してください。これは /octo:debate と同じ、独立した統合的な視点です。
プロバイダーを示して、すべての批評を表示します:
🔴/🧭/🟡 **External Provider Critique:** [implementation, ecosystem, accessibility, and alternative approach concerns]
🔵 **Claude Critique:** [design concerns — accessibility gaps, fit issues, missing patterns]
利用可能なプロバイダーが1〜2つだけの場合は、利用できるもので実行してください。Claude のみでの批評(最小構成)でも、「選択を行ったデザイナー」から「問題を見つけるレビュー担当者」へ明確に視点を切り替えるため、有益です。
すべての批評を集めた後、内容を統合して改訂します:
- 問題をトリアージする — 重大度ごとに分類します(必ず修正、修正すべき、トレードオフとして容認)
- 必ず修正する項目に対応する — コントラストに合わせて色を調整し、実用的でないフォントを置き換え、不足しているパターンを追加します
- 修正すべき項目に対応する — 可能な範囲で取り入れ、先送りする場合はその理由を記録します
- トレードオフを記録する — 批評を受けても維持する点と、その理由を文書化します
- 差分を示す — 当初の方向性から改訂後の方向性への変更点を提示します:
📋 **Design Direction Revisions:**
- [Changed] Primary blue #2563EB → #1D4ED8 (contrast ratio 4.2:1 → 5.8:1, per external critique)
- [Added] Fallback font stack for body text (per external critique)
- [Kept] Glassmorphism style despite provider concern — appropriate for SaaS dashboard audience
改訂したデザインの方向性をフェーズ3に引き継ぎます。批評を受けていない方向性で進めてはいけません。
ステップ 6:フェーズ3 — 開発(デザインシステム)
ユーザーが求める成果物に基づいて、デザインシステムを生成します:
デザイントークン(要求された場合):
- CSS カスタムプロパティまたは Tailwind 設定
- カラースケール(50〜950)
- スペーシングスケール(基本単位は4px)
- 行高を含むタイポグラフィスケール
- シャドウ、角丸、トランジションのトークン
コンポーネント仕様(要求された場合):
- コンポーネントの構造図(ASCII)
- Props/バリアントの表
- 状態のバリアント(デフォルト、ホバー、アクティブ、無効、エラー、読み込み中)
- アクセシビリティ要件(ARIA、キーボード、フォーカス)
ページレイアウト(要求された場合):
- レスポンシブブレークポイントを備えたグリッドベースのレイアウト
- コンテンツ階層と視覚的な流れ
- ファーストビューのコンテンツ戦略
- ナビゲーションとインタラクションのパターン
スタイルガイド(要求された場合):
- 検索結果の根拠を示したビジュアルスタイルの理由
- 例を含む推奨事項と禁止事項
- アイコンとイラストのガイドライン
- モーションとアニメーションの原則
shadcn MCP が利用可能な場合は、一致するコンポーネントを検索します:
// Search shadcn registries for components matching the design system
mcp__shadcn__search_items_in_registries({ query: "<component name>" })
ステップ 7:フェーズ4 — 提供(検証)
- アクセシビリティ監査 — 目視で済ませず、チェッカーを実行します。 トークンセット内のテキストと背景の各組み合わせを、コントラスト検証ツールにかけます:
python3 "${HOME}/.claude-octopus/plugin/scripts/helpers/contrast-check.py" \
'<text-hex>:<bg-hex>' '<heading-hex>:<bg-hex>:large' '<muted-hex>:<bg-hex>' ...
終了コード1は、少なくとも1つの組み合わせが WCAG AA に準拠していないことを意味します。パレットを修正し、提供前に再実行してください。証拠として、最終ドキュメントにチェッカーの出力を含めます。
- 粗雑さのチェック —
skills/blocks/design-taste.mdにある公開前チェックリストを実行します。2つ以上の項目に不備がある場合は、提供前に改訂します - 完全性のチェック — 要求された成果物がすべて揃っていることを確認します
- 実装準備状況 — 仕様が frontend-developer にとって十分詳細であることを確認します
- Figma への反映(接続されている場合)— デザイントークンを Figma に反映することを提案します
STEP 7b:AI サーフェス監査(インターフェースがモデルを呼び出す場合)
設計対象がモデルに入力を送り、その結果を表示する場合は必ず実施してください。特に、その結果に基づいて何らかの操作を行う場合は重要です。スタイルガイドやコンポーネント仕様では、AI 機能に何を表示し、ユーザーが何を制御できるようにすべきかは定まりません。このステップで確認します。モデルが関与しないインターフェースでは、このステップを完全に省略してください。
各質問に回答し、明示的に記録してください。「該当なし」は有効な回答ですが、無回答は認められません。
1. 不確実性。 サーフェスでは、自信のある回答と推測を区別できますか?区別できない場合は、信頼性が一様であるかのように示すのではなく、そのことを明確に述べてください。数値のしきい値を独自に設定せず、基盤となるシステムが実際に根拠を示せる表現を選んでください。
2. 出典。 ユーザーは回答の根拠を確認できますか?検索・情報取得機能には引用が必要です。要約機能には、要約した元の情報が必要です。出典をたどれない回答は、検証できません。
3. 中断。 出力がストリーミングされる場合や、タスクに時間がかかる場合、キャンセルする手段はありますか?また、キャンセルによって処理が実際に停止しますか、それとも表示が消えるだけですか?実行中のジョブを放置する停止ボタンは、システムの状態を誤って伝えるため、何もないより悪いものです。
4. レビューゲート。 人が出力を確認するのはどの時点ですか?また、その配置は重要な役割を果たしていますか?取り消せない操作の後にあるゲートは、単なる飾りです。skill-intent-contract では、率先して行動する範囲、制御権、意思決定権がすでに個別に確認されています。ここでは改めて導き出すのではなく、それらの回答を再利用してください。回答と配置が一致しない場合は、契約を優先してください。
5. 失敗と機能低下。 モデルの応答が遅い場合、利用できない場合、レート制限に達した場合、または利用できない結果が返された場合、サーフェスには何が表示されますか?それぞれに異なる状態が必要です。すべてを一般的なエラーにまとめると、ユーザーはそれを無視するようになります。
6. 同意とデータの利用。 何がどこに送信され、保持されるかどうかをユーザーは把握していますか?入力に他者のデータが含まれる可能性がある場合は、必ず明確にしてください。
7. ロールバック。 機能が現実世界で何らかの操作(ファイルの操作、送信、支払い、削除)を行う場合、その操作を取り消す方法は何ですか?また、その方法は失敗した後だけでなく、操作を行う前に確認できますか?
出力要件。 提出する文書では、7 項目すべてに回答し、それぞれの判断とその根拠を記載してください。基盤となるシステムが対応できず、質問に回答できない場合は、欄を空白にせず、その事実を調査結果として記録してください。ロールバックに関する質問に回答できないことは、記載漏れではなく、設計上の制約です。
出典の明記。 この枠組みは、Brandon Harwood による AI Interaction Atlas(ai-interaction.com)に基づいています。参考にするのであって、コピーしないでください。Atlas には、信頼度のしきい値やレイテンシの予算といった数値基準が意図的に設けられていません。ここでそれらを独自に設定すると、公開されていない数値を出典に帰属させることになります。方向性を示し、出典を引用したうえで、具体的な値はプロダクト側で定めてください。
STEP 8: 結果を提示して保存する
最終的なデザインシステムを、以下を含む構造化されたドキュメントとしてまとめます。
- エグゼクティブサマリー(スタイルの方向性とその根拠)
- デザイントークン(コピーしてすぐに使える形式)
- コンポーネント一覧
- ページレイアウト
- 開発チーム向けの実装メモ
- ソース(各判断の根拠となった検索結果)
デザインシステムをセッション後も残るように保存します(契約:skill-design-lineage)。
SLUG=$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")
RAW_BRANCH=$(git branch --show-current 2>/dev/null || true)
REVISION=$(git rev-parse HEAD 2>/dev/null || printf 'unborn')
if [[ -n "$RAW_BRANCH" ]]; then
BRANCH_KEY=$(printf '%s' "$RAW_BRANCH" | tr '/' '-')
else
RAW_BRANCH="detached:${REVISION}"
BRANCH_KEY="detached-${REVISION}"
fi
DATETIME=$(date -u +"%Y%m%d-%H%M%S")
DESIGNS_DIR="${HOME}/.claude-octopus/designs/${SLUG}"
mkdir -p "$DESIGNS_DIR"
# DESIGN_BODY must contain the complete structured design system from this step.
if [[ -z "${DESIGN_BODY:-}" ]]; then
echo "Design persistence failed: DESIGN_BODY is empty." >&2
exit 1
fi
# Serialize revision allocation per branch with an OS-managed lock. Closing the
# descriptor releases the lock even after SIGKILL or a process/host crash.
LOCK_DIGEST=""
if command -v sha256sum >/dev/null 2>&1; then
LOCK_DIGEST=$(printf '%s' "$RAW_BRANCH" | sha256sum | awk '{print $(1)}') || LOCK_DIGEST=""
elif command -v shasum >/dev/null 2>&1; then
LOCK_DIGEST=$(printf '%s' "$RAW_BRANCH" | shasum -a 256 | awk '{print $(1)}') || LOCK_DIGEST=""
else
echo "Design persistence failed: no supported SHA-256 utility." >&2
exit 1
fi
if [[ ! "$LOCK_DIGEST" =~ ^[[:xdigit:]]{64}$ ]]; then
echo "Design persistence failed: could not derive the branch lock key." >&2
exit 1
fi
LOCK_FILE="${DESIGNS_DIR}/.${LOCK_DIGEST}.lineage.lock"
LOCK_HELD=false
FILEPATH=""
TEMP_PATH=""
cleanup_design_persistence() {
[[ -n "${TEMP_PATH:-}" && -f "$TEMP_PATH" ]] && rm -f "$TEMP_PATH"
[[ -n "${FILEPATH:-}" && -f "$FILEPATH" && ! -s "$FILEPATH" ]] && rm -f "$FILEPATH"
if [[ "$LOCK_HELD" == true ]]; then
exec 9>&-
LOCK_HELD=false
fi
}
trap cleanup_design_persistence EXIT
trap 'cleanup_design_persistence; exit 1' HUP INT TERM
if ! exec 9>"$LOCK_FILE"; then
echo "Design persistence failed: could not open the lineage lock." >&2
exit 1
fi
if command -v flock >/dev/null 2>&1; then
if flock -n 9; then LOCK_STATUS=0; else LOCK_STATUS=$?; fi
elif command -v lockf >/dev/null 2>&1; then
if lockf -s -t 0 9; then LOCK_STATUS=0; else LOCK_STATUS=$?; fi
else
exec 9>&-
echo "Design persistence failed: no supported file-lock utility (flock or lockf)." >&2
exit 1
fi
if [[ "$LOCK_STATUS" -ne 0 ]]; then
exec 9>&-
echo "Design persistence failed: another revision is being persisted for $RAW_BRANCH." >&2
exit 1
fi
LOCK_HELD=true
# Discover the newest prior document for this exact branch or detached revision.
PRIOR=""
for candidate in "$DESIGNS_DIR"/*.md; do
[[ -f "$candidate" ]] || continue
candidate_branch=$(awk -F ': ' '$(1) == "branch" { print $(2); exit }' "$candidate")
[[ "$candidate_branch" == "$RAW_BRANCH" ]] || continue
[[ -z "$PRIOR" || "$candidate" -nt "$PRIOR" ]] && PRIOR="$candidate"
done
SUPERSEDES=""
[[ -n "$PRIOR" ]] && SUPERSEDES=$(basename "$PRIOR")
USER_NAME="${USER:-$(whoami)}"
REVISION_ID="${DATETIME}-$$-${RANDOM}"
FILEPATH="${DESIGNS_DIR}/${USER_NAME}-${BRANCH_KEY}-design-${REVISION_ID}.md"
# Reserve the final name atomically. The timestamp is readable; PID + RANDOM
# prevents same-second runs from choosing the same immutable revision.
if [[ -e "$FILEPATH" ]] || ! (set -o noclobber; : > "$FILEPATH") 2>/dev/null; then
echo "Design persistence failed: revision target already exists: $FILEPATH" >&2
exit 1
fi
if [[ -n "$SUPERSEDES" && "$SUPERSEDES" == "$(basename "$FILEPATH")" ]]; then
rm -f "$FILEPATH"
echo "Design persistence failed: a revision must not supersede itself." >&2
exit 1
fi
if ! TEMP_PATH=$(mktemp "${FILEPATH}.tmp.XXXXXX"); then
echo "Design persistence failed: could not allocate a temporary file." >&2
exit 1
fi
if ! {
printf '%s\n' '---'
printf 'branch: %s\n' "$RAW_BRANCH"
printf 'user: %s\n' "$USER_NAME"
printf 'created: %s\n' "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
printf 'git_revision: %s\n' "$REVISION"
[[ -n "$SUPERSEDES" ]] && printf 'supersedes: %s\n' "$SUPERSEDES"
printf '%s\n\n' '---'
printf '%s\n' "$DESIGN_BODY"
} > "$TEMP_PATH"; then
echo "Design persistence failed: could not write complete temporary document." >&2
exit 1
fi
if [[ ! -s "$TEMP_PATH" ]]; then
echo "Design persistence failed: temporary document is missing or empty." >&2
exit 1
fi
PUBLISHED_PATH="$FILEPATH"
if ! mv "$TEMP_PATH" "$FILEPATH"; then
echo "Design persistence failed: could not publish $FILEPATH." >&2
exit 1
fi
TEMP_PATH=""
FILEPATH=""
exec 9>&-
LOCK_HELD=false
trap - EXIT HUP INT TERM
printf 'Persisted design: %s\n' "$PUBLISHED_PATH"
後続のセッション(および flow-develop / frontend-developer への引き継ぎ)では、最新のリビジョンを選択する前に、~/.claude-octopus/designs/<slug>/ から branch: が現在の Git ブランチと一致するドキュメントのみを絞り込む必要があります。detached HEAD の場合は、detached:<full-commit> のブランチ値を使い、そのリビジョンと完全に一致するドキュメントのみを選択してください。supersedes をたどるのは、絞り込み後の集合内に限ります。各リビジョンは、以前のドキュメントを編集するのではなく、そのドキュメントに取って代わります。
次のステップを提案します。
- 「これらの仕様を実装しますか?」→ frontend-developer ペルソナに引き継ぎます
- 「パレットを調整しますか?」→ 検索クエリを調整してカラー検索を再実行します
- 「フルの embrace ワークフローを実行しますか?」→
/octo:embraceに移行します