BlackAgents App Patterns
適用タイミング
app/**、app/api/**、または lib/** に触れる機能や修正を実装する際に読むこと。ハード制約は typescript-strict ルールと api-response-format ルールにあります。このファイルはレイヤーとレシピを説明します。
アーキテクチャ(レイヤーを尊重せよ)
UI (components/features/, client) ──fetch──▶ API routes (app/api/**/route.ts)
│ { success, data | error }
Domain (lib/artifacts/, lib/standards/)
│ parse / serialize / graph
Filesystem (lib/fs-service.ts)
│ resolveInWorkspace (no escape)
Workspace folder (.cursor / .claude ...)
運用ルール:
- 純粋でプラットフォームに依存しないロジックは
lib/artifacts/**に配置する。React やnext/serverをインポートしてはならない。 - HTTP 関連の処理は
app/api/**/route.tsのみに記述する。 - すべてのディスクアクセスは
lib/fs-service.tsを経由する。ルートから直接node:fsを呼び出してはならない。
App Router 規約
- ページはデフォルトでサーバーコンポーネントとする。インタラクティブ性、状態、エフェクトが必要な場合のみ
"use client"を追加する。 - ルートグループ:
/agents、/commands、/rules、/skillsにはそれぞれ一覧ページ、[name]編集ページ、newページがあり、/newはガイド付きウィザード。その他のルート:/graph、/standards、/export、/sync、/chat、/providers、/settings。 - クライアント機能コンポーネントは
apiFetch(lib/api.ts) を介してフェッチし、アクティブなワークスペースの状態をWorkspaceProviderから読み取る。クライアント内で生のfetchや直接の設定読み取りを行ってはならない。
API ルートレシピ
import { ok, fail, handle } from "@/lib/api-response"
import { artifactInputSchema } from "@/lib/artifacts/schemas"
export async function POST(req: Request) {
return handle(async () => {
const parsed = artifactInputSchema.safeParse(await req.json())
if (!parsed.success) return fail(parsed.error.issues[0].message, 400)
// ...domain work via lib/artifacts + lib/fs-service...
return ok({ /* data */ })
})
}
- 常に
ok/failで応答を返す。handleでラップすることで、スローされた例外が500エンベロープになるようにする。 - ワークスペースルートは設定 (
lib/config.ts) から読み取り、resolveInWorkspace(root, relPath)を使用する。 - 秘密情報はサーバーサイドでのみ
lib/secrets.tsで読み取る。認証情報がない場合はfail("...", 412)を返す。
ドメインモデル
lib/artifacts/:
types.ts—Artifact、ArtifactType、Platform、ArtifactFrontmatter(ツール非依存)。layout.ts—PLATFORM_LAYOUTS+artifactRelPath()/artifactDeletePath()。プラットフォームのフォルダと拡張子を知る唯一の場所。ACTIVE_PLATFORMS = ["cursor", "claude"]、デフォルトはcursor。parser.ts—scanWorkspace(root)とparseArtifact(gray-matter使用)。スキルは<name>/SKILL.mdディレクトリとして再帰的に探索される。serializer.ts—serializeArtifact(input)は frontmatter と本文を書き出す。ルールはnameを省略(ファイル名で識別)。schemas.ts—nameSchema(ケバブケース)、artifactInputSchema、normalizeExtra(タイプ別 frontmatter)。graph.ts— オーサリング規約から相互参照を抽出する。
相互参照規約(グラフが読み取るもの)
| 元 → 先 | 本文中の規約 |
|---|---|
| コマンド → エージェント | エージェント名(太字) |
| エージェント → ルール | `ルール名` ルール |
| エージェント → スキル | `スキル名` スキル |
| ルール → ルール | 関連ルール: a, b. |
| ルール → スキル | 関連項目: x スキル. |
これらの正確な規約で本文を記述することで、関係グラフとアシスタントのリンク検出が機能するようになります。
ファイルシステムの安全性
export function resolveInWorkspace(root: string, relativePath: string): string {
// relativePath を root の下で解決し、エスケープする場合は WorkspaceError をスローする
}
すべての読み書きは、この関数を介してワークスペース相対パスから構築されなければなりません。絶対パスを連結したり、クライアントから提供された絶対パスを受け入れたりしてはいけません。
ワークスペース外の永続化
~/.black-agents/config.json— 保存されたワークスペース + アクティブなcurrentPath(lib/config.ts)。~/.black-agents/secrets.json— LLM キー、モード0600、サーバーサイドのみ(lib/secrets.ts)。<workspace>/.black-agents/standards.md— ワークスペースごとのオーサリング規約のオーバーライド。- 設定ディレクトリは
BLACK_AGENTS_CONFIG_DIRでオーバーライド可能(テストで便利)。
使用方法
参照専用。ペルソナとワークフローは feature-developer エージェントにあり、ガードレールは typescript-strict ルールと api-response-format ルールにあります。このファイルを使用してロジックを適切なレイヤーに配置し、ルートレシピをコピーしてください。その後、UI は uiux-designer エージェントに、テストカバレッジは tester エージェントに委ねてください。