本文へ移動
cccskills
無料GitHub で公開日本語紹介

compose-atoms

大きな機能を、画面や共有ページごとに必要な能力だけ読み込む部品へ分け、状態や処理の置き場所も整理する設計指針です。

原文原文の説明を見る

Use for splitting heavy domains into capabilities (原子组件) across page, portal, share or micro-app hosts, sinking state (状态下沉) and replacing mode/readOnly flags. Simple component splits: react.

lobehub/lobehubスター 83,506(GitHub 83,506 + cccskills 0)

実行スコア 未検証

インストール方法を見る

こんなときに便利

  • 複数の画面で機能を共有したいとき
  • 軽量な画面に不要な機能を読み込みたくないとき
  • 機能ごとに状態と処理を分けたいとき
  • modeやreadOnlyの条件分岐を整理したいとき

日本語での紹介

できること

大きな機能を、ページ、ポータル、共有画面、マイクロアプリなどの利用先が必要なものだけ組み合わせられる「能力単位」に分ける設計ガイドです。見た目だけを小さく分割するのではなく、ある利用先が読み込まずに済ませたいまとまりを部品として切り出します。データ取得、表示用データ、画面内の一時状態、更新処理はそれを使う部品側に置き、組み立て側はレイアウトと読み込む部品の選択を担います。これにより、使わない機能の依存モジュールまで軽量な画面に取り込む構造を避けやすくなります。

こんなときに便利

同じ機能を通常画面と公開ページなど複数の場所で使い、利用先ごとに編集や操作機能の有無を変えたいときに向いています。機能追加のたびにmodeやreadOnlyの条件分岐が増えている場合や、画面から状態を切り離したい場合にも使えます。単一画面の単純なコンポーネント分割にはreactを使います。

使い方の例

  • 「この機能をページと公開画面で使うため、能力ごとの部品と組み立て方を整理してください」
  • 「読み取り専用フラグをなくし、編集機能を必要な画面だけで読み込む構成にしてください」
  • 「データ取得と一時状態を適切な部品に移してください」

注意点

分割後は、軽量な利用先のimportツリーを確認し、不要なモジュールが読み込まれないことを確かめます。

この紹介文は、公開されている SKILL.md をもとに AI(OpenAI Codex)が作成しました。正確な仕様は下の原文を確認してください。

資料チェック

SKILL.md の記述から、注意が要る操作と導入の前提を AI が確認しました。点数は実際に動かした結果(実行検証)だけで付けています。

安全面送信・削除・コマンド実行などの扱いが明示されているか
A良好記載された操作は設計・import確認で、削除や外部送信はありません。
導入のしやすさ必要なツールや API キーが少ないか、書かれているか
A良好Reactの設計ガイドで、追加ツールや認証情報の前提はありません。

点数には入れていません。 2026年10月26日 時点で AI(OpenAI Codex)が判定しました。目安なので、入れる前に原文も確認してください。

評価が違うと思ったら、見直しを依頼する

どの項目が、なぜ違うと思うかを書いてください。ログインは不要です。内容を SKILL.md と照らし合わせて評価を作り直し、この欄に反映します。

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

含まれるファイル(1)

  • SKILL.md10.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Compose Atoms

A heavy domain is a kit, not a viewer with modes. Each host is an import list. An atom owns the data, actions, and dependencies of one capability. The assembler only chooses what to mount.

This is a module-graph split. Hiding UI does not drop a module. A host that never imports a file is the only host that does not ship it.

Do not use this skill to slice one component into smaller files. That is react.

When

The folder is a product surface (Conversation, Acceptance, Document, Verify, Task, …) and at least one of these is true:

  • One entry owns read + write + workflow + host integration.
  • A second host already exists or is the next change (page, portal, share, mobile, popup, micro-app).
  • The next feature is another boolean / mode / variant on the fat tree.
  • Reusing a header, list, or card would import trays, stores, or chat.

If the file is large but has one capability and one host, stop. Use react.

Grain

An atom is the smallest unit a host is allowed not to mount.

Ask, for every chunk: would any host ship the rest and skip this? If yes, it is an atom. If no, it stays inside its parent.

That grain is coarser than a visual section and finer than the whole page.

Too coarseRight grainToo fine
One Viewer with readOnlyIdentity, goal, list, decision, …Every badge, row, and icon as a public export
Chat as a single importList, composer, intervention, …Every message sub-row the page then rewires
Document as editor + every panelCanvas, header, comments as omittedInternal toolbar buttons

A workflow (focus review, thread, publish) is one atom to hosts that skip the whole mode. Inside it, keep splitting only if a host would mount a piece of that workflow alone.

Sink State

The split is worthless if the assembler still holds the domain state. Imports follow the hook. A useStore / useX / handleAccept left on the page keeps that module (and everything it imports) on every host that mounts the page.

Sink everything the atom needs into the atom:

Sinks into the atomStays on the assembler
Resource fetchThe record id / scope identity
Derived view model (counts, labels, scope)Which atoms are mounted (the import list)
Transient UI (filter, collapse, pending)Host layout state (focused vs overview, rail)
Mutation handlers and their stores/modalsHost seams (provider value the runtime owns)
// wrong — visual split, state still on the page
const Page = () => {
  const { data, mutate } = useX(id);
  const [filter, setFilter] = useState('all');
  const accept = () => void mutate(...);
  return (
    <>
      <Identity data={data} />
      <List data={data} filter={filter} onFilter={setFilter} />
      <DecisionBar onAccept={accept} />
    </>
  );
};

// right — each atom reads and acts; page only assembles
const Page = () => (
  <Scope id={id}>
    <Identity />
    <List />
    <Decision />
  </Scope>
);

Do not lift "to fetch once" or "so siblings share data". Two atoms calling the same SWR hook share the cache by key. Sibling writes go through that cache (or a store slice the write atom imports), not through page useState.

Lift only when the state is the assembler's job: which workflow is on screen, whether a rail is open. If a value is used to render or mutate one capability, it belongs in that capability.

Kit

PieceOwnsMust not own
Domain primitiveTypes, predicates, formattersReact, stores, services
Data accessOne resource, one fileSibling list / infinite / document hooks
Read atomPresent + local UI state + its own fetchMutations, trays, owner services, host stores
Write atomOne mutation and its UIPage layout, unrelated writes
Workflow atomA mode assembled from other atomsBecoming the only entry other hosts can import
Domain slotReactNode hole for another same-domain atomA callback whose implementation lives in this file
Host seamOptional host-provided UI, null by defaultA fallback that imports the host graph
AssemblerLayout + the import listDomain actions; domain fetch except local chrome

A visual block that both reads and writes is a read atom + a write atom, joined by a domain slot.

Two seam types — do not mix them:

  • Domain slot — same feature, optional capability (editSlot, toolbar). The host imports the write atom and passes it in.
  • Host seam — only some runtimes can resolve it (chat store, topic drawer, Electron). Context default is null. The micro-app / share page never imports the provider value. See split-micro-app for the runtime cut.

Ownership

State and imports live in the atom that needs them.

  • Read atoms call the isolated resource hook. Filter / collapse / expand stay in the atom.
  • Write atoms call the same hook, then mutate. They import their own modals and services. They return null when the record is not writable.
  • Workflow atoms compose other atoms. They still do not become the light host's entry.
  • Assemblers do not fetch in order to push props down. Chrome unique to that host (a title in a shell header) may read the hook.
  • Scope context carries identity (id, embedded). It does not carry actions, stores, or modal openers.

Several atoms calling the same SWR hook is expected. SWR dedupes on key. Do not lift data to the assembler "to fetch once".

The shared read hook is its own file. A light host imports that file, never a hooks.ts / store barrel that also exports list, document, or send-message.

// any host:
import { useX } from '@/features/Domain/useX';

// never from a light host:
import { useX } from '@/features/Domain/hooks';
import { DomainViewer } from '@/features/Domain';

A flag that only changes behavior of code already in the atom is fine. A flag whose purpose is to skip importing another module is not — that module is a slot or a sibling the assembler omits.

dynamic(() => import(...)) only helps when no static import of that module remains on the light graph.

Assembler

A host is its import list.

// light host — deep imports only
<Scope id={id}>
  <ReadA />
  <ReadB />
</Scope>

// full host — same reads, write atoms in slots, workflows as siblings
<ReadA extra={<WriteA />} />
<ReadB toolbar={<WriteB />} />
<Workflow />
<WriteC />

Route / portal files compose host skeleton (providers, host seams). Do not add a wrapper page whose only job is to sit between the route and the assembler.

The feature barrel may export the full assembler for in-app use. Light hosts must not import that barrel.

Procedure

  1. List hosts (page, portal, share, mobile, popup, micro-app — include the next one).
  2. List capabilities as verbs (view identity, edit field, decide, open host thing). Map host → verbs.
  3. Set grain: each verb a host can skip is an atom. Group the rest under a parent.
  4. Extract primitives and the isolated read hook first.
  5. Extract read atoms. Optional same-domain capabilities become ReactNode slots, not callbacks that close over write modules.
  6. Extract each write / workflow atom into its own file. Heavy deps stay in that file.
  7. Sink state. Move fetch, view-model, transient UI, and handlers out of the assembler. If the page still calls a domain hook to feed props, the split is not done.
  8. Rewrite every host as an import list plus layout. Delete readOnly / isPublic / mode / variant on the fat tree.
  9. Point light hosts at atoms by deep path.
  10. Prove the cut. Grep the light entry's import tree, or trace a module the light host must not ship. A missing button is not proof.
# example: light host must not import a write atom
WORKBENCH_TRACE_MODULE=features/Acceptance/Viewer/Review/AcceptanceDecision bun run build:rr

If the light assembler appears on the importer chain, a static import still exists — usually a barrel, a leftover flag, or actions left on the page.

Example

src/features/Acceptance/Viewer/ is one application of this kit, not the template to copy file-for-file.

HostMounts
In-app Acceptance/index.tsxIdentity, goal, inventory, decision, focus workflow, ledger + write slots
Workbench public detailIdentity, goal, inventory, discussion with sign-in guidance
PortalFull assembler + OriginConversationProvider

Read AcceptanceGoal (read + editSlot) and AcceptanceGoalEdit (write) for the slot cut. Read originConversation.tsx for a host seam. Read workbench AcceptanceDetail.tsx for a light assembler.

Related skills

  • react: single-surface boundaries, styling, memoization.
  • split-micro-app: worker / SSR / gateway / stubs. This skill is how the shared UI is cut afterwards.
  • spa-routes: route files stay thin assemblers.
  • data-fetching-architecture: how the isolated hook fetches, not where a host may import it from.
  • zustand: narrow selectors inside an atom; do not put the whole store on scope context.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

acceptance

無料概要あり

実際の製品を操作して、利用者が確認できる動作証拠を集め、検証計画に沿った受け入れレポートとして公開するスキルです。

  • 変更後の製品動作を実地で検証したいとき
  • 画面キャプチャなどの証拠を集めたいとき
  • 検証計画とレポートを作成したいとき
lobehub/lobehub8.4万2026年10月26日 更新

add-model-provider

無料概要あり

LobeHubにAIモデルプロバイダーを追加し、実行時連携からモデル表示、設定、ブランド表記、文書化、動作確認まで進めるスキルです。

  • 新しいAIモデルプロバイダーを追加したいとき
  • プロバイダーの設定手順や説明文を更新したいとき
  • 既存プロバイダーへのモデル追加要件を見極めたいとき
lobehub/lobehub8.4万2026年10月26日 更新

add-setting-env

無料概要あり

ユーザー設定の初期値をサーバー側の環境変数で切り替えるため、型定義や設定の組み立て、ユーザーストアへの反映、環境変数の例と説明書きを追加する手順です。

  • 設定の初期値を環境変数で変えたいとき
  • 設定項目をサーバー設定に追加したいとき
  • 環境変数の例と説明を更新したいとき
lobehub/lobehub8.4万2026年10月26日 更新

agent-runtime-hooks

無料概要あり

エージェント実行中の各段階をフックで監視し、ツール呼び出しの模擬・制御や人の承認、圧縮、サブエージェント処理に介入する仕組みを扱います。

  • エージェントの実行状況を記録したいとき
  • ツール結果をテスト用に模擬したいとき
  • Webhookでツール実行を許可・拒否したいとき
lobehub/lobehub8.4万2026年10月26日 更新

agent-signal

無料概要あり

イベントを起点にエージェントのバックグラウンド処理を組み立て、ソース・シグナル・アクション・ポリシーの役割分担や非同期連携を実装するためのスキルです。

  • イベント起点の処理を追加したいとき
  • バックグラウンド処理を非同期化したいとき
  • 重複実行を防ぐ仕組みを整えたいとき
lobehub/lobehub8.4万2026年10月26日 更新

agent-testing-bot

無料概要あり

DiscordやSlackなどの実際のチャットアプリでボットにメッセージを送り、応答を画面で確認する受け入れテストを行うスキルです。

  • 実際のDiscordでボット応答を確かめたいとき
  • SlackやTelegramの会話経路をテストしたいとき
  • macOSアプリ上の操作結果を画面で記録したいとき
lobehub/lobehub8.4万2026年10月26日 更新

lobehub のスキルをすべて見る

このスキルの問題を報告する