ワンクリックで
crowi-migration
// Crowi 2.0 移行ワークフロー。Express/Swig から Next.js + Hono への移行時に自動適用。 キーワード: migrate, 移行, Express, Swig, legacy, 旧実装
// Crowi 2.0 移行ワークフロー。Express/Swig から Next.js + Hono への移行時に自動適用。 キーワード: migrate, 移行, Express, Swig, legacy, 旧実装
Crowi 2.0 の新機能開発ワークフロー。設計合意 (会話で詰めた spec) を起点に、 spec → planner → implementer → simplify → reviewer → committer まで自動で進める。 キーワード: feature, 新機能, 開発, build, 設計, spec
完了した並行 worktree の作業を main に取り込み、worktree を close、その後 simplify で 統合後のコードを整える一連のワークフロー。複数エージェントが gw worktree で並行作業して いる時に、ひとつ終わったブランチを main に合流させる時に使う。 キーワード: worktree, merge, integrate, gw end, 統合, 取り込み
| name | crowi-migration |
| description | Crowi 2.0 移行ワークフロー。Express/Swig から Next.js + Hono への移行時に自動適用。 キーワード: migrate, 移行, Express, Swig, legacy, 旧実装 |
| globs | ["packages/api/src/hono/**","packages/api-contract/src/**","packages/web/src/app/**"] |
Crowi の旧 Express + Swig + jQuery を、新 Hono API + Next.js に段階的に置き換える。 1人開発・main 直コミット運用が前提。
注: 旧 Express/Swig レイヤーと中間の ts-rest 実装は RFC-0006 (2026-05-22 main マージ) で完全撤去済み。core wiki 機能の移行はほぼ完了しており、この skill は主に残作業・ 新規エンドポイント追加の参照用。
crowi/ # Turborepo + pnpm workspace
├── apps/crowi-site/ # crowi.wiki LP + docs (移行対象外)
├── crowi.config.json # dev runner config (plugins + active drivers)
├── .env(.example) # dev runtime env (repo root で読まれる)
└── packages/
├── api/ # Hono API (port 4301)
│ └── src/
│ ├── hono/ # ★ Hono app: handlers/ (admin/ 含む) + middleware/ + app.ts
│ ├── models/ # Mongoose
│ ├── crowi/ # boot sequence
│ └── util/ # helpers
├── api-contract/ # Hono (@hono/zod-openapi) + Zod 契約 (src/{contracts,schemas})
├── web/ # Next.js 16 App Router (port 4302)
│ └── src/app/
│ ├── (public)/ # ログイン前
│ ├── (auth)/ # ログイン後 (jwtAuth)
│ └── (admin)/ # 管理画面 (jwtAdminRequired)
├── runner/ # config loader + plugin resolver (api boot で使用)
├── collab/ # Hocuspocus 協調編集ホスト (RFC-0003)
├── admin-cli/ # `crowi-admin` CLI
└── plugin-*/ # storage / renderer / search プラグイン
エンドポイントは packages/api/src/hono/handlers/ に集約。旧 controllers/ / routes/
/ views/ は撤去済みで存在しない。
@hono/zod-openapi + Mongoose + JWT (jwtAuth middleware)ページ作成 (POST /api/v2/pages) を例に:
// packages/api-contract/src/contracts/page.ts — @hono/zod-openapi の route 定義
export const createPageRoute = createRoute({
method: 'post',
path: '/pages',
tags: ['page'],
security: [{ bearerAuth: [] }],
request: { body: { content: { 'application/json': { schema: CreatePageRequestSchema } } } },
responses: {
200: { description: 'Created page', content: { 'application/json': { schema: PageWithRevisionSchema } } },
400: { description: 'Bad request', content: { 'application/json': { schema: ApiErrorSchema } } },
},
});
// packages/api/src/hono/handlers/page.ts — route を openapi() で登録
export const registerPageRoutes = (app, crowi) => {
app.use('/pages/*', createJwtAuth(crowi));
return app.openapi(createPageRoute, async (c) => {
const user = c.get('user');
const body = c.req.valid('json');
const created = await Page.createPage(body.path, body.body, user, { grant: body.grant });
return c.json({ page: pageToResponse(created) }, 200);
});
};
<!-- 旧: packages/api/views/page/list.html -->
{% for page in pages %}<div>{{ page.path }}</div>{% endfor %}
// 新: packages/web/src/app/(auth)/[[...slug]]/page.tsx
'use client';
const { data } = useQuery(['pages'], () => client.page.listPages());
return data?.body.pages.map(p => <div key={p._id}>{p.path}</div>);
/migrate {feature}
planner ──→ implementer ──→ simplify ──→ reviewer ─┬→ committer
↑ ↑ │
└─────── NEEDS_WORK ───────┴───────┘
各 phase の責務:
simplify skill を呼び、reuse / quality / efficiency を整える.migration-state/ (リポジトリ root) ※ .claude/migration-state/ ではない.gitkeep のみ tracked)queue.json: アクティブタスクとグローバル configtasks/{task-id}.json: 各タスクの真実 (status はここが正){
"currentTask": "migrate-pages-create",
"config": {
"commitStrategy": "main-direct",
"maxReviewAttempts": 3,
"runSimplify": true
},
"lastUpdated": "2026-05-05T..."
}
tasks/ に存在するファイルが真実。queue.json に各タスク status を二重で持たせない。
tasks/{id}.json){
"id": "migrate-pages-create",
"name": "ページ作成 API の移行",
"status": "PLANNED",
"context": {
"oldImpl": [
"packages/api/src/controllers/page.ts:554-583 (api.create)",
"packages/api/src/routes/api/page.ts:10"
],
"newImpl": [
"packages/api/src/hono/handlers/page.ts (createPage)"
],
"contracts": [
"packages/api-contract/src/contracts/page.ts (createPage)",
"packages/api-contract/src/schemas/page.ts (CreatePageRequestSchema)"
],
"models": ["packages/api/src/models/page.ts"],
"relatedPRs": ["#894", "#896"],
"architecturalNotes": "authenticatedRouter で jwtAuth 適用済み、CSRF 不要"
},
"acceptanceCriteria": ["..."],
"openQuestions": ["..."],
"history": [
{"phase": "planner", "at": "...", "by": "agent"},
{"phase": "implementer", "at": "...", "by": "agent"}
]
}
context は planner が埋め、後続 agent はそれを読むだけで作業できる(プロンプトでの補完不要)。
PLANNED → IN_PROGRESS → REVIEW → (APPROVED → COMMITTED) | NEEDS_WORK → IN_PROGRESS → ...
commitStrategy: main-direct では COMMITTED で完結 (CI 監視・DONE 遷移なし)。
# 新規移行
/migrate pages.update
# 計画だけ
Use migration-planner to plan: pages.update
# 個別 phase
Use migration-implementer to implement: migrate-pages-update
Use migration-reviewer to review: migrate-pages-update
Use migration-committer to commit: migrate-pages-update
--crowi-primary: #43676b;
--crowi-header: #263a3c;
--crowi-sidebar: #f8f9fa;